i had a problem with an object, that i resolved. But i don’t understand how. The thing is, i have a provider:
@Injectable()
export class wpapi {
private url: string = 'http://www.quotys.dev/wp-json/wp/v2/posts?fields=id,date,modified,link,categories,tags,x_featured_media_original,acf.autor,acf.wikipedia,acf.origen,acf.frase,acf.contexto,acf.avatar.url&filter[orderby]=rand';
private posts: any;
constructor(public http: Http) {
console.log('Hello WpApi Provider');
}
allPosts() {
if (this.posts) {
return Promise.resolve(this.posts);
}
// Dont have the data yet
return new Promise(resolve => {
this.http.get(this.url)
.map(res => res.json())
.subscribe(data => {
this.posts = data;
resolve(this.posts);
});
});
}
}
Then in my home.ts page:
export class Home {
public posts: any;
constructor(public navCtrl: NavController, public apiCtrl: wpapir) {
this.getDataAPI();
}
private getDataAPI() {
this.apiCtrl.allPosts().then(data => {
console.log(data);
this.posts = this.randomize(data);
this.loading.dismiss()
});
}
And when i try to show posts i dont want to use *ngFor becouse i just want to show only the first post, but {{ posts[0].something }} show me an error, that something is undefined but if i use *ngFor it works:
<div *ngFor="let post of posts">
{{ post.something }}
</div>
By chance i found this solution that it works: {{ posts && posts[0].something }}
But don’t get it, why i need to repeat posts and use &&?
So… as far as i can see it does not matter if i set it like posts: Object[]; or posts: Array<Object>; or whatever becouse the data is not resolved yet.
Is a good solution to use posts && posts[0]? i mean, about performence, is what i really care about.
I dont want to use ionViewWillEnter becouse i dont want to query the same data all the time, for update things i have other plans in mind.
I don’t think so. It’s ugly and offloads too much work onto the template, whereas making sure all publicly exposed properties are always in a sane state should be the component’s job. I prefer initializing posts inline, like so:
posts: Post[] = [];
Make a proper Post interface instead of relying on any. I also hate the way allPosts is constructed. I know the Ionic generator tool creates this code and it’s all over the place in samples, but it packs a lot of antipatterns into a small space. Here’s how I would do it instead:
export class Wp {
posts: Subject<Post[]> = new ReplaySubject<Post[]>;
fetchPosts(): Observable<Post[]> {
let req = this.http.get(url).map((rsp) => {
// naked arrays in JSON are not a great idea, but I assume you can't control this
return rsp.json();
});
req.subscribe((posts) => {
this.posts.next(posts);
});
return req;
}
}
Allows other places to tickle a refresh of communication with the backend that will be seamlessly picked up with no extra work in the Home component (or anywhere else that needs it)
Home’s data never goes stale
Errors are properly propagated out and can be caught where desired