0

I have a component that makes use of a service, inside the service is a HTTP call to a server that contains data regarding release notes for a product. The release notes are simply returned as a JSON string.

I want to be able to obtain the JSON value from the server and then return the value from the service to the parent class that called the method in the first place. This way I am able to use the JSON string in the parent class.

I'm not sure what the best way to go about this is. Should I be using a BehaviourSubject with a getter that the parent class can access? If so how do I adapt the below code to make use of a behaviour subject?

Service method

getLatestReleaseNote() {
    let releaseNoteUrl = this._configService.getConfig().releaseNoteUrl;
    const currentVersion = this.getCurrentVersion();
    releaseNoteUrl += currentVersion.replace(".", "_") + ".json"; 
    const releaseNoteDataStream = this._httpClient.get<string>(releaseNoteUrl).pipe(take(1)); //Need to subscribe or pass to BehaviourSubject
  }

Alternatively, can I just subscribe to the releaseNoteDataStream observable and return the value from inside the subscription? Like below?

getLatestReleaseNote(): string {
    let releaseNoteUrl = this._configService.getConfig().releaseNoteUrl;
    const currentVersion = this.getCurrentVersion();
    releaseNoteUrl += currentVersion.replace(".", "_") + ".json"; 
    const releaseNoteDataStream = this._httpClient.get<string>(releaseNoteUrl).pipe(take(1)).subscribe(val => 
      {
        return val;
      });
  }

I realise this is incorrect but I'm not sure how I go about returning from a subscription.

For a third alternative, could I use an EventEmitter to emit the string value when the subscription has a value?

Jake12342134
  • 1,539
  • 1
  • 18
  • 45
  • There is no return value of a subscription. You needs to asign val to a variable. – MoxxiManagarm Sep 12 '19 at 10:12
  • What exactly is the problem here? Are your attempts not working or are you getting some error? – Nicholas K Sep 12 '19 at 10:13
  • @NicholasK Neither, the issue is that I don't know how to proceed in line with Angular best practices. I can hack something together that'll work but that's not my aim – Jake12342134 Sep 12 '19 at 10:14
  • In your parent component you can declare the service in the constructor as public and use it's variables in you component. So if you have something like ```public comunicationService: ComunicationService``` and then you can call like ```comunicationService.val``` in your component. Don't forget to make the variable public in the service and assign to it the response. ```...subscribe(val => { this.val = val; }); ``` – Kiril1512 Sep 12 '19 at 10:18

3 Answers3

1

Your best bet would be to use Angular EventEmitter. Even emitters are meant to send data to parent components. They can be synchronous as well as asynchronous to suit your needs.

Also, you can just fetch the release notes in the parent component and pass it on to child components using @Input() decorator.

kiranghule27
  • 439
  • 1
  • 7
  • 20
0

You can do the manipulation of the data inside the parent class by just returning the observable result from your http call and do the subscription in your parent class - something like below -

// parent class method
parentClassMethod() {
    this.releaseNoteService.getLatestReleaseNote().subscribe(data => { // assuming your service was added as constructor parameter
        this.doStuffToData(data); //manipulate the local data in other parts of the parent class - like if data is not a json string, serialize or do JSON.stringify(data)
    });
}

// service class method
getLatestReleaseNote() {
    let releaseNoteUrl = this._configService.getConfig().releaseNoteUrl;
    const currentVersion = this.getCurrentVersion();
    releaseNoteUrl += currentVersion.replace(".", "_") + ".json"; 
    return this._httpClient.get(releaseNoteUrl).pipe(take(1));
  }

Note: Make sure your httpClient.get function is an actual httpClient.get function

For the other suggestion as in the comments, please see: How to pass a callback as a function

Ian Preglo
  • 421
  • 2
  • 10
  • Ah so return the observable, this makes sense. Is there no way to return the actual value emitted by the observable though? – Jake12342134 Sep 12 '19 at 10:15
  • there is, and that will be to set a local variable inside your service class, and provide a callback function from your parent class as parameter to your service method - which will be a headache later - on :D so just do the simple thing and return the observable – Ian Preglo Sep 12 '19 at 10:18
0

I feel comfortable with Promise while working with http. So I preferred to return Promise from service instead of Observable and use .then(), .catch() callbacks.

 return this.http.get(this.categoryURL, v)
    .map(response => response.json())
    .toPromise();

One advantage of observables is, that you can cancel the request. Check Angular - Promise vs Observable

Dipak Telangre
  • 1,792
  • 4
  • 19
  • 46