2016-10-25 4 views
0

eine Liste von Dokumenten zu machen, ich .map() auf einer Funktion, die einen Array aus dem Abonnement zurückzugibt:einziges Dokument Render mit Meteor Reagieren

{this.getApplications().map((application) => { 
    return application.name; 
})} 

Aber wenn ich will ein einzelnes Dokument wie folgt machen:

export default class ApplicationForm extends TrackerReact(React.Component) { 

    constructor() { 
    super(); 
    this.state = { 
     subscription: { 
      applications: Meteor.subscribe('applications') 
     } 
    } 
    } 

    componentWillUnmount() { 
    this.state.subscription.applications.stop(); 
    } 

    getSingleApplication() { 

    const applicationDoc = Applications.find().fetch(); 

    if (applicationDoc) { 
     return applicationDoc[0]; 
    } 
    } 

    render() { 

    const name = this.getSingleApplication().name; 

    return (
     <div> 
      {name} 
     </div> 
    ); 
    } 
} 

bekomme ich folgende Fehlermeldung:

Cannot read property 'name' of undefined

ich denke, ich habe habe etwas grundlegendes Javascript verpasst.

Oder hat es möglicherweise damit zu tun, dass Abonnements beim Laden der Seite nicht bereit sind?

+0

Können wir mehr Code sehen? – Li357

+1

'this.getSingleApplication()' gibt undefined zurück. Nicht viel mehr können wir tun. –

+0

'Kann Eigenschaft 'name' von undefined nicht lesen - bedeutet, dass Sie JavaScript lernen müssen ... getSingleApplication gibt undefined zurück ... – Endless

Antwort

0

Erstens .findOne() verwenden, wenn Sie ein einzelnes Dokument finden möchten. Dies gibt ein Objekt anstelle eines Cursors zurück, so dass Sie nicht .fetch() oder .map() benötigen.

getSingleApplication() { 
    return Applications.findOne(); 
} 

Dann brauchen Sie defensiv, falls nichts codieren gefunden wird (was passieren kann, wenn Ihr Abonnement zum Beispiel nicht bereit ist).

render() { 

    const app = this.getSingleApplication(); 
    const name = app && app.name; 

    if (name) { // assuming you don't want to render anything if there is no name 
    return (
     <div> 
     {app.name} 
     </div> 
    ); 
    } 
} 
+0

Danke für die Aufklärung! Das Dokument wird viele Eigenschaften haben, brauche ich eine if-Anweisung für jede Eigenschaft? –

+0

Hängt davon ab. Werden alle Eigenschaften immer zusammen da sein oder können sie in irgendeiner Kombination auftreten? Wenn sie immer zusammen sind, dann mache einfach 'if (app)' –

0

Haftungsausschluss: Ich habe Meteor nie benutzt und dies wird nicht getestet.

Sie müssen eine Möglichkeit haben, auf Ihr Abonnement zu reagieren, wenn es 'fertig' ist. Wenn ich die Dokumente richtig verstehe, tun Sie dies, indem Sie beim Abonnieren eine Rückruffunktion übergeben. So

Sie benötigen

constructor() { 
    super(); 
    this.state = { 
     ready: false, 
     subscription: { 
      applications: Meteor.subscribe('applications',() => this.setState({ready: true}) 
     } 
    } 
    } 

und in machen:

render() { 
    if (!this.state.ready) return null; 
    const name = this.getSingleApplication().name; 

    return (
     <div> 
      {name} 
     </div> 
    ); 
    }