I have a set of "article" documents stored in an "articles" collection in a Firestore no-SQL database. I am pulling these articles into an Angular 6 (^6.0.3) project using angularfire2 (^5.0.0-rc/10) and firebase (^5.0.4). The data is held in a service as observables and then pulled into various components and converted into objects when needed.
I am having a strange issue when I try to display properties of the object in HTML through interpolation and data binding. It simply does not show anything. I click an article tile from a menu, pass the article id as a string to my service, and then create an observable that points to the article with the corresponding id. I then subscribe to the observable in my component class and store the data as an object. The object prints fine on its own, but if I reference different properties it acts as if there is no data.
This is the code from the controller for my component:
article: any = {};
articleString: string;
selectArticle(articleId: string) {
this.articlesService.getArticleObs(articleId).subscribe((data) => {
this.article = data;
this.articleString = JSON.stringify(this.article);
});
}
Which calls this function in the service:
getArticleObs(articleId: string) {
console.log('article id sent to service: ' + articleId);
this.articleDoc = this.db.doc(`articles/${articleId}`);
return this.articleDoc.valueChanges();
}
and should display here in the HTML:
<ng-template #article>
<div class="article-body">
<div fxLayout="row">
<div class="article-image">
<img [src]="article?.game.image">
</div>
<div class="article-header" fxLayout="column">
<div>{{this.article?.title}}</div>
<h1>{{ article?.game?.title }} Review:</h1>
<div fxLayout="row">
<h2>Title:{{ article?.title }}</h2>
<h2>Author:{{ article?.author }}</h2>
</div>
</div>
</div>
<div class="article-content" [innerHTML]="article?.content"></div>
<div class="article-comments">
Comments:{{ article?.comments }}
</div>
</div>
<h3>{{ articleString }}</h3>
</ng-template>
I can console.log(article) and get a complete object.
I also get a complete object showing on the screen with {{articleString}} but for any of the other interpolation or databinding there is no data.
Can anyone tell me why the HTML thinks that the object properties are empty strings?
UPDATE:
I just tried this in my controller:
selectArticle(articleId: string) {
this.articlesService.getArticleObs(articleId).subscribe((data) => {
this.article = data;
console.log(1 + this.article);
this.articleString = JSON.stringify(this.article);
console.log(2 + this.article);
});
console.log(3 + this.article);
}
The result in the console makes me think it is an async issue. The 3 prints first with an empty object. The 1 prints next with the complete object and then the 2, also with a complete object.
2 Things you can try (If you haven't already):
1) Use parenthesis (do the same for all your bindings):
<h1>{{ (article)?.game?.title }} Review:</h1>
2) Use the async
pipe to unwrap the Observable, change your selectArticle
method:
selectArticle(articleId: string) {
// Don't subscribe here
this.article = this.articlesService.getArticleObs(articleId);
}
In the template (do the same for all your bindings):
<h1>{{ (article | async)?.game?.title }} Review:</h1>
Sidenote: You also have a typo in your code, this line:
<div>{{this.article?.title}}</div>
should not be using this
<div>{{article?.title}}</div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.