2

I have been reading post and googling an answer for this question without any success

I looked into these two links and nothing

Angular doesn't update view when array was changed

Updating HTML view when Angular array changed

I have two components (siblings) one component add Items and the other lists all items added. The idea is very simple, whenever someone adds an item I want to update the list in order to get that new item.

export class ListItem implements OnInit {
  list: SomeObject[] = [];

  constructor(private myService: SomeService) {}

  ngOnInit() {
    this.getItems();
  }

  getItems(): void {
    this.myService.getDomesticatedPokemons()
      .subscribe((newItems) => {
        this.list = newItems; // I can see that this line works as expected but the view doesn't get updated though
      });
  }
}

export class AddItem implements OnInit {
  constructor(private myService: SomeService, private list: ListItem) {}

  ngOnInit() {

  }

  saveItem(aForm: NgForm): void {
    // ...
    // ...
    // ...
    // ...

    this.myService.addItem({}).subscribe((result) => {
      if (result.ok === 1) {
        this.list.getItems();
      } else {
        console.error('Error: ...');
      }
    });


  }
}

UPDATE:

this is the view:

<!-- This is the list template -->
<div id="list">
    <div *ngFor="let item of list" class="item">
       ...
       ...
       ...
    </div>
</div>

for the add component there is a form and saveItem() is executed on submit

UPDATE 2: I created a stackblitz this example is working even though I couldn't (or at least I didn't know how) reproduce my service getting data from server. I commented out "more realistic" code the main component is list.

9
  • stackoverflow.com/questions/34827334/… Commented Dec 3, 2018 at 17:44
  • we can't get the big picture without seeing the view/tepmlate/html Commented Dec 3, 2018 at 18:11
  • @Chellappan Thanks for the link, I already tried ChangeDetectorRef.detectChanges() but didn't work. I'll try the other two now. benshabatnoam I added the HTML as requested Commented Dec 3, 2018 at 18:35
  • @benshabatnoam: I added the view and some comments as requested, :-) Commented Dec 3, 2018 at 18:39
  • Post a complete minimal example as a stackblitz. the code of the service, the decorators of your components, are necessary information. Commented Dec 3, 2018 at 18:40

1 Answer 1

3

I have tried to solve your problem statement:

component to insert into the list

view:

<h3>create list</h3>
Foo:
<input type="text" class="form-field" [(ngModel)]="newItem.foo"><br/>
Bar:
<input type="text" class="form-field" [(ngModel)]="newItem.bar"><br/>
<button class="btn" (click)="addItem()">Add</button>
<button class="btn" (click)="resetForm()">Reset</button>
<hr>

controller:

export class CreateListComponent  {
  public newItem:Object;

  constructor(private listService: ListService) {
    this.newItem = this.setInital();
  }

  private setInital(){
    return {
      foo: null,
      bar: null
    };
  }
  public addItem(){
    this.listService.addItem(this.newItem);
    this.resetForm();
  }

  public resetForm(){
    this.newItem = this.setInital();
  }
}

component to display the list

view:

<h3>display list</h3>

<div *ngFor="let item of list">
  {{item.foo}} - {{item.bar}}
</div>

controller:

export class DisplayListComponent implements OnInit, OnDestroy {
  public list = [];
  private subscription: Subscription;

  constructor(private listService: ListService) { }

  ngOnInit() {
    this.getList();
  }

  private getList() {
    this.subscription = this.listService.getFooBarList().subscribe(data => {
        this.list.push(data);
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Since both the components are at same hierarchy, I have used service and observable to pass data from create component to display component

service:

export class ListService {
  private listSubject = new Subject();

  constructor() {}

  public addItem(item: any) {
    this.listSubject.next(item);
  }

  public getFooBarList() {
    return this.listSubject.asObservable();
  }
}

I hope this helps you. For a working sample please refer this stackblitz.

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

2 Comments

Thanks for the response, @Shrinivas. one question, what's the idea or logic behind this line this.subscription = this.listService.getFooBarList().subscribe( in display-list.component.ts??
It is about observables. The list a stream data (something like a TV channel which broadcasts some programme). I am subscribing to that channel. I get notified each time a new item is streamed. this.subscription is a handler to the subscription. When I do not want to to be notified, I will unsubscribe to that channel.

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.