1

My service return two list of items and I want to render each list to difference selector

this.http.get(url).map(res => res.json())

the json returns { list1: [...], list2: [...] }

and I have two <div> to render list1 and list2.

Is it possible to do with Angular JS 2?

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
tarn
  • 546
  • 6
  • 10
  • Yes, it is. But it shouldn't be much different from the way you'd do it for a single list. What's holding you back? – acdcjunior Mar 03 '16 at 01:32
  • You could do [inputs] for child components, [outputs] and event-emitter to parent components to receive them, or is it another completely seperate part of your application? If that's the case you could use a redux-store or use an observable and watch for changes to an object to update different pieces of your application. If you want to do that, make sure you add it into your bootstrap so there is only one instance of it within your application. – Morgan G Mar 03 '16 at 04:38

2 Answers2

0
class MyService {
  private _list1;
  private _list2;

  getList1() {
    if(this._list1) {
      return Observable.of(this._list1);
    } else {
      return _getList(1);
    }
  }

  getList2() {
    if(this._list2) {
      return Observable.of(this._list2);
    } else {
      return _getList(2);
    }
  }

  private _getList(listNo) {
    return this.http.get(url).map(res => {
      var json = res.json();
      this._list1 = value.list1;
      this._list2 = value.list2;
      if(listNo == 1) {
        return json.list1;
      }
      if(listNo == 2) {
        return json.list2;
      }
    });
  }
}
@Component({
  selector: 'my-component1',
  pipes: [KeysPipe],
  template: `
  <ul>
     <li *ngFor="let item of list | keys">{{item.key}} - {{item.value}}</li>
  </ul>
`
})
export class MyComponent1 {
  constructor(private MyService myService) {
    myService.getList1().subscribe.(value => this.list = value);
  }
}
@Component({
  selector: 'my-component2',
  pipes: [KeysPipe],
  template: `
  <ul>
     <li *ngFor="let item of list | keys">{{item.key}} - {{item.value}}</li>
  </ul>
`
})
export class MyComponent2 {
  constructor(private MyService myService) {
    myService.getList2().subscribe.(value => this.list = value);
  }
}

If you want to render both lists in the same component it can be simplified of course.

For the KeysPipe see access key and value of object using *ngFor

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

I don't know how you trigger the call for your request. Another component for example.

You could also define two EventEmitter properties (one per list) into your service to emit events when the response of your HTTP call is there. Two components can subscribe on it to be notified when data are there.

  • Service implementation

    export class ListService {
      list1Event: EventEmitter<any> = new EventEmitter();
      list2Event: EventEmitter<any> = new EventEmitter();
    
      getLists() {
        return this.http.get(url).map(res => res.json())
          .subscribe(
            (data) => {
              this.list1Event.emit(data.list1);
              this.list2Event.emit(data.list2);
            }
          );
      }
    }
    
  • Component #1 implementation

    @Component({
      selector: 'my-component1',
      template: `
        <ul>
         <li *ngFor="#item of list">{{item.name}}</li>
        </ul>
      `
    })
    export class MyComponent1 {
      constructor(private service:ListService) {
        this.service.list1Event.subscribe.(data => {
          this.list = data;
        });
      }
    }
    
  • Component #2 implementation (similar but for list2)

  • Component that triggers the execution of the HTTP call

    @Component({
      selector: 'other-component',
      template: `
        <div (click)="executeRequest()">Execute request</div>
      `
    })
    export class OtherComponent {
      constructor(private service:ListService) {
      }
    
      executeRequest() {
        this.service.getLists();
      }
    }
    

See this question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • The EventEmitter does not trig on the MyComponent. I think service object is not the same instance in each component see http://plnkr.co/edit/sd8FvFva428g4gibRXKP?p=preview – tarn Mar 03 '16 at 15:32
  • Yes you need to specify it when bootstrapping your application to be able to share the same instance... – Thierry Templier Mar 03 '16 at 15:53