Mellville
Mellville

Reputation: 1097

Angular 6: can't display values fetching localStorage

I can save, read or update data with localstorage. But im trying to use a Model to display all users (id and userName) with the directive *ngFor. But I get the error: "Only arrays and iterables are allowed". I'm missing something; can someone help me out?

The simple model:

export interface User {
  id:number;
  userName:string;
}

The HTML:

<input class="form-control" [(ngModel)]="test" >
      <button (click)="saveUser(test)" class=" btn btn-danger">SAVE</button>
<div>
  <button (click)="readUser(test)" class=" btn btn-danger">Read</button>
</div>
<div>
  <ul *ngFor="let user of test">
    <li>{{user.id}}</li>
    <li>{{user.userName}}</li>
  </ul>
</div>

And the component class:

export class Testing implements OnInit {

  test: User[]=[];

  constructor() { }

  saveUser(user:string){

    localStorage.setItem('userName', JSON.stringify(user));

    console.log(user)
  }

  readUser(){
    console.log(JSON.parse(localStorage.getItem('userName')) 
  }

Upvotes: 0

Views: 657

Answers (2)

Pankaj Shukla
Pankaj Shukla

Reputation: 2672

You can have following ts file:

   test = '';
  _id = 0;
  users: User[] = [];

  constructor() { }

  saveUser(user: string) {
    this.users.push({id: this._id++, userName: this.test});

    localStorage.setItem('userName', JSON.stringify(this.users));

    console.log(user);
  }

  readUser() {
    console.log(JSON.parse(localStorage.getItem('userName')));
  }

and the following template(html) file.

<input class="form-control" [(ngModel)]="test" >
      <button (click)="saveUser(test)" class=" btn btn-danger">SAVE</button>
<div>
  <button (click)="readUser(test)" class=" btn btn-danger">Read</button>
</div>
<div>
  <ul *ngFor="let user of users">
    <li>{{user.id}}</li>
    <li>{{user.userName}}</li>
  </ul>
</div>

Notice that you cannot treat test as an array. Because test is bound with input tag and is a string not array.

In order to treat something as array for *ngFor introduce another property called users as shown in the code.

Upvotes: 1

Jeto
Jeto

Reputation: 14927

You need to give your input a name such as #userInput and pass its value to saveUser with:

<button (click)="saveUser(userInput.value)" ...>

saveUser must also add the user to your test (should be users) array.

Script

export class Testing {
  private currentId = 0;
  test: User[] = [];

  saveUser(userName: string) {
    this.test.push({id: ++this.currentId, userName})
    // ...
  }
}

View

<input #userInput class="form-control">
  <button (click)="saveUser(userInput.value)" class=" btn btn-danger">SAVE</button>
<div>
  <button (click)="readUser(test)" class=" btn btn-danger">Read</button>
</div>
<div>
  <ul *ngFor="let user of test">
    <li>{{user.id}}</li>
    <li>{{user.userName}}</li>
  </ul>
</div>

StackBlitz demo

Upvotes: 1

Related Questions