3

I'd like to refresh my card set from navigation bar which is part of app.component.html so I prepared refresh() function.

When it is called it does update variable Cards but doesn't render it in ngFor on html element in mainView.html.

It does render updated set if I call from html element in mainView.html (as (click)="loadCards()") but not if the same ((click)="refresh()") is done in app.component.html.


export class MainView implements OnInit {

  constructor(private mMainController: MainController) {}

  Cards: any = [];

  ngOnInit() {
    this.loadCards();
  }

  loadCards() {
    this.mMainController.getAllCards().subscribe(
      (data) => {this.Cards = data); },
      (error) => {},
      () => {console.log(this.Cards));
  }

...
}

export class AppComponent {
  ...

  constructor(private router: Router, private mMainView: MainView) {}

  refresh(){
    console.log('done');
    this.mMainView.loadCards();
  }
  ...
}

Update

Tried with @Input() but couldn't get it work. I implemented RefreshService as explained in accepted answer and now I'm able to refresh content from other components.

Thank you all for quick response.

Penguin74
  • 480
  • 6
  • 19
  • I think the issue comes from the way you call MainView, which doesn't seem to trigger a digest. I think the correct way to do this would be to pass your cards array as an input to your component `[cards]=cards` and then modifying the cards array directly from the child component. – Anton Bks Aug 19 '19 at 17:21

3 Answers3

7

FIST WAY: USING A SHARED SERVICE

You need to introduce a service that manage the state of your car.

In this case it may be usefull to introduce for this a BehaviorSubject like this:

Your Service:


private refresh: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

public getRefresh(): Observable<boolean> {

   return this.refresh.asObservable();
}

public setRefresh(value: boolean): void {

   this.refresh.next(value);
} 

Inside your MainView class

  • First: inject your service as dependency
  • Second: Subscribe to your observable inside OnInit hook e.g like this:
this.myService.getRefresh().subscribe((value: boolean) => {
    if(value) {

      this.loadCards()
    }
  
})

Inside your AppComponent class

  • First: inject your service as dependency
  • Second: Set the value of your observable inside your refresh method.

e.g something like this:


public refresh(){
    this.myService.setRefresh(true);
}

SECOND WAY: USING @Input Decorator to pass value down.

billyjov
  • 2,778
  • 19
  • 35
0

You're attempting to use MainView as a dependency but it's not an injectable dependency. Try to use inputs/outputs between app component and MainView, if possible. If MainView isn't a child of AppComponent then abstract the logic for loading cards into a service and inject it into both.

0

You can implement the component interaction in two ways

(i) If the components are related to each other use the common and straightforward method of sharing data. It works by using the @Input() decorator to allow data to be passed via the template.

(ii) If the components are not related to each other you can use a shared service using subject to communicate between the two components

Sajeetharan
  • 216,225
  • 63
  • 350
  • 396