Displaying content synchronously with angular2

I have a contacts page, whenever I add a contact by pushing the contact to an array which is displayed with *ngfor let c of contacts) it doesn’t display the new contact without me refreshing the page. I guess this is because the page has to be reloaded in order to display new content with angular2. Are there any ways to generate the output automatically without reloading the page?

If you set your page up correct, you don’t need a refresh. How does your contactpage looks like (HTML and TS)? If you push the contact to a local binded ngFor, it should definitely show the content without a refresh.

<ion-item ngFor="let item of items">
    <ion-icon name="person" item-left></ion-icon>
    {{item.Name}} 
    <div class="right"> 
      <button (click)="edit(item.Name, item.PostCode, item.id)" ion-button icon-only>
       <ion-icon name="create"></ion-icon>
      </button>
    </div>
</ion-item>

export class AboutPage {
public newName;
public newPostCode;
public newId;

items: any;
constructor(public navCtrl: NavController, public storage: Storage, private alertCtrl: AlertController,public navParams: NavParams) {
this.storage.get(‘myStore’).then((data) => {
this.items = data;
}

This is your actual code? Because it already seems to miss an * (asterisk) at the start of ngFor?

Yes it is my actual code, I tried changing it to ngFor without the asterisk, it didn’t work. Then when I sent you the code and forgot to change it back to *ngfor.

Okay. And where is the code that you’re using to try and push a new item to the array?

saveContact(name, postcode){

this.storage.get('myStore').then((data) => {
  if(data != null)
  {
    let id = data.length     
    data.push({"id": id ,"Name": name, "PostCode": postcode})
    this.storage.set('myStore', data);
    console.log(data);
    console.log("hello buddy"+data.length);
  }
  else{
    let id = 0;
    let array = [];
    array.push({"id": id,"Name": name, "PostCode": postcode})
    this.storage.set('myStore', array);

  }

});

}

Okay, so this makes sense. You’re iterating over items. Items gets filled by doing this.storage.get(mystore) and then you’re setting this.items = data. So far so good… Then when you try to save the contact, you’re doing a get on the storage again and set your (new) item to the storage. There’s no place where you’re updating the displayed contacts (i.e. your local this.items) again. Since this.storage.get and set actively retrieve items from your storage, you also have to reassign the values of this.items again (to the newly retrieved values). Does that make sense?

Btw, why do you get the data again when saving it? Wouldn’t it be sufficient to just push the new contact to this.items and then save the new list again to your storage?

So what must i do?

this.items.push({“id”: id ,“Name”: name, “PostCode”: postcode}

?

I could do that, how would I save the new list (this.items) to the storage?

something like this?

pushItem() {
          this.items.push({"id": id ,"Name": name, "PostCode": postcode});
          console.log('my new items list',this.items);
          this.storage.set('myStore',this.items);
    }

This updates your local list (this.items) and then pushes the new list to your storage at the place of myStore.

With your suggested code the the following error is thrown: cannot not read property “push” of null.

For the code I have before the following happens:whenever the page is first loaded these errors get thrown. But once the storage has been filled everything seems to work fine (look at GIF)

I think for some reason this.items isn’t getting declared UNTIL data starts being stored in it? Because

here is my save contact function for the GIF above:

saveContact(name, postcode){

this.storage.get('myStore').then((data) => {
  this.items = data;
  if(data != null)
  {
    console.log("if");
    let id = data.length     
    data.push({"id": id ,"Name": name, "PostCode": postcode})
    //this.items.push({"id": id ,"Name": name, "PostCode": postcode})
    this.storage.set('myStore', data);
    console.log(data);
    console.log("hello buddy"+data.length);
  }
  else{
    console.log('else');
    let id0 = 0;
    let array = [];
    array.push({"id": id0,"Name": name, "PostCode": postcode})
    //this.items.push({"id": id0,"Name": name, "PostCode": postcode})
    this.storage.set('myStore', array);
    console.log(data.length);
  }
});

}

If you don’t assign a value to items, off course you have to give it a value first. So, items: any = [] is enough to declare AND initialize the array. After that, you can push items to it. If you want to get some items from storage first, just check storage as you did before with this.storage.get when loading the view. Then assign the retrieved items to this.items. Now you can use the save function as I opposed.

It could be as simple as this:

@Component({
  selector: 'page-name',
  templateUrl: 'pagename.html',
})
export class namePage {

  items: any = [];

  constructor() {
    this.storage.get('myStore')
      .then((data) => {
        if (data) {
         this.items = data;
        } else {
          // do nothing
        }
      })
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad Login');
  }


	saveContact() {
	      this.items.push({"id": id ,"Name": name, "PostCode": postcode});
	      console.log('my new items list',this.items);
	      this.storage.set('myStore',this.items);
	}


}

It would be nice to actually respond to help when asking questions over here… It feels a little bit dissatisfying when I see you put up new posts and then don’t respond on older ones. Did you manage to get it working?