0

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')) 
  }
3
  • anyone, please? Commented Oct 23, 2018 at 22:01
  • You're mapping an input (text, so a string) to an array. So when you type characters into the input, the array gets overwritten by the corresponding string and it's no longer an array, making *ngFor unable to iterate over it. What exactly is that input supposed to do? Add a user to the array? Commented Oct 23, 2018 at 22:04
  • yes, I want to save as many users as possible, then display them Commented Oct 23, 2018 at 22:12

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Great! Thank you very much for the explanation and the stackBlitz. Greetings, Jeto
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.