0

I just started playing with angular 2 and i've ran into a small problem, that i ve searched for in various forms and also angulars documentation.

I've managed to make a service that makes a call and then i want in a component when i press a button to load another component with dynamicload component and have access to the ajax result.

The problem is that I can t figure out how to do that..

The question is how can I make the result accesible in other components using Observables or Promises method.

2 Answers2

0

If I understood correctly your question, you are looking a way to insert a data from request to another nested component.

I hope this image will clarify for you the data flow for this case.

Component interaction

  1. Your Root component is calling a service method which returns for you promise object.
  2. Then you map needed data from response to the component model inside Root Component constructor.
  3. And your Child component should be subscribed for the model which you was preparing in previous step.

    ngOnInit() {
    this.dataService.getSomeData()
        .subscribe((data: IData) => {
            this.data = data;
        });
    

    }

Just a short example above how to set model in the root component from the promise object to the local model.

New research:

There is another way to fill your components by data from api's. You can use EventEmitter to emit event from service, and then, you can subscribe for this event inside you created components, so they will get a data, each time there will be called the service. Here is nice example of this strategy in the first answer. Service Events

Hope it will help you, let me know if you will need additional info!

Community
  • 1
  • 1
Kanso Code
  • 7,479
  • 5
  • 34
  • 49
  • Mikki thanks but can I do this in another component which is not a child component ? They are unrelated and one injects the other trough dynamiccomponentload.. – Obretin Alexandru Apr 21 '16 at 19:42
  • @Obretin I do not know your architecture, a bit difficult to understand why do you need such case, if you where using ng1, I would say you should use `event broadcasting` but ng2 is using more strictly data flow concept. So you can try to call service from the parent component, or probably provide more details, and I will help you with pleasure :) – Kanso Code Apr 21 '16 at 19:50
  • well the things I may be doing things wrong but I have a searchbox in the top of the page and when I press the submit button I want to load another component in the middle of the page ( or maybe have it loaded from the start ) and after I receive the answer from the API populate the components template with the answer. The thing is that if I make the call the component renders but dosen t have the ajax call.. If you have any advice please tell me.. kinda new to the whole angular 2 stuff – Obretin Alexandru Apr 21 '16 at 20:28
  • Ok, I see, I will add some info to my answer. Let me know is that will not help you, cheers – Kanso Code Apr 22 '16 at 05:04
0

Just create a service, then inject the service where you want. Here it's an example how to share a service ajax data across many components without making the request twice : https://stackoverflow.com/a/36413003/2681823

the Service:

@Injectable()
export class DataService {
    constructor(private http: Http) { }

    private _dataObs = new ReplaySubject<request>(1); 

    getData(forceRefresh?: boolean) {
    // On Error the Subject will be Stoped and Unsubscribed, if so, create another one
    this._dataObs = this._dataObs.isUnsubscribed ? new ReplaySubject(1) : this._dataObs;

    // If the Subject was NOT subscribed before OR if forceRefresh is requested
    if (!this._dataObs.observers.length || forceRefresh) {
            this.http.get('http://jsonplaceholder.typicode.com/posts/2')
              .subscribe(
                requestData => {
                  this._dataObs.next(requestData);
                },
                error => this._dataObs.error(error));
        }

        return this._dataObs;
    }
}

the Component:

@Component({
  selector: 'child',
  template : `<button (click)="makeRequest()" class="btn">Click me!</button>`
}) 
export class Child {
  constructor(private _dataService: DataService) {  } 

  makeRequest() {
    this._dataService.getData().subscribe( 
      requestData => {
          console.log('ChildComponent', requestData);
      }
  }
}

A full working example/plunker can be found here : http://plnkr.co/edit/TR7cAqNATuygDAfj4wno?p=preview

Community
  • 1
  • 1
Tiberiu Popescu
  • 4,486
  • 2
  • 26
  • 38
  • Tanks @tibs, but I have done this.. it's now what i'm looking for.. BTW I see that there are a million ways to do this – Obretin Alexandru Apr 21 '16 at 20:30
  • Lets say that you have a form that when submited calls for a API response and then the result must go to another component that will use the response – Obretin Alexandru Apr 21 '16 at 20:41
  • Even in this example from plunker how do I process the response let's say in an *ngFor in the template – Obretin Alexandru Apr 21 '16 at 21:07
  • You need a service that will be updated on the API response. So in the API response you call something like **service.setReponse(responseData)** and also in the service have another method something like **service.getResponse()** to use where you want. But probably needs to be a bit different, as those needs to be of type Observables. So you need something like this http://stackoverflow.com/questions/33675155/creating-and-returning-observable-from-angular-2-service/36020225#36020225 – Tiberiu Popescu Apr 21 '16 at 21:16
  • I swear that everytime I find something about how to aproach Observables and the http subject in angular 2 it looks different ( 10 variation till now ).. I am more confused then before – Obretin Alexandru Apr 21 '16 at 21:48
  • In your example how can you use the response in the template {{requestData.title}} for example – Obretin Alexandru Apr 21 '16 at 22:18
  • Instead of the console.log('ChildComponent', requestData); You write something like : **this.requestData = requestData** and also declare **requestData: any;** in the Class – Tiberiu Popescu Apr 22 '16 at 15:23
  • I've managed to make this work if I make the call in the component... but how can I make the call in one component and use the result in another totally unrelated component, For example I have a form and when i press submit I make and ajax call and receive some data.. and then I need it in an results Component that is unrelated to the form component,, I've tried with @Input but with no success – Obretin Alexandru Apr 26 '16 at 09:41