What means && in HTML template?


#1

Hello!

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 &&?

Thanks in advance.


Single array JSON object will not print
#2

It is just because you have initialized posts like private posts: any; and not any array.

whwn you load your HTML , the this.apiCtrl.allPosts() takes time to resolve. So until its resolved posts[0] will be undefined,

{{ posts && posts[0].something }} --> this simply means print it when posts get defined. thats why it works.

Instead of constructor, call this.getDataAPI(); in ionViewWillEnter if you want to refresh data everytime the page opens.


#3

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.

Thanks! and sorry if my bad english.


#4

nothing wrong about it ! I use it all the time. Infact , it saves extra pain of keeping check on undefined variables.


#5

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;
  }
}
export class Home {
  posts: Post[] = [];
  constructor(private _upstream: Wp) {
    this._upstream.posts.subscribe((posts) => {
      this.posts = posts;
    });
    this.refresh();
  }

  refresh() {
    this._upstream.fetchPosts();
  }
}
  • Eliminates needless Promise nonsense
  • 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

#6

Thanks man, this was really helpful!

At first time i didn’t understand it, but now that i am working with observables, i get it!!!