How to set a value from observable to a variable in Angular 2
Asked Answered
S

2

8

I have a UsernameService that returns an observable which contains a json object. In AnotherService, I want to inject a value from the UsernameService object.

So far, I am able to subscribe to the observable from UsernameService and I can show it in the console. I can even drill down and show one of the values from the object in the console. However, I don't understand how to assign that value to a variable that I can then use. Instead, when I try to assign the value to a variable, in the console I get: Subscriber {closed: false, _parent: null, _parents: null...etc

Here's my example where I am successfully showing the observable value in the console:

import { UsernameService } from './username.service';
import { Injectable, OnInit } from '@angular/core';
import 'rxjs/Rx';

@Injectable()
export class AnotherService {

    username: any[] = [];

    constructor(private getUsernameService: UsernameService) { }

    someMethod() {
        let myFinalValue = this.getUsernameService.getUsername()
        .subscribe(username => console.log(username.data[0].AccountName));
    }
}

The code above results in the console correctly showing the value of the AccountName field which I am trying to assign to the variable myFinalValue. However, I cannot seem to figure out where I am going wrong.

When I try to use the same technique to simply get the value (instead of log in console), I get the generic: Subscriber {closed: false, _parent: null, _parents: null...etc as I mentioned before.

Here's an example of the code that results in my error:

import { UsernameService } from './username.service';
import { Injectable, OnInit } from '@angular/core';
import 'rxjs/Rx';

@Injectable()
export class AnotherService {

    username: any[] = [];

    constructor(private getUsernameService: UsernameService) { }

    someMethod() {
        let myFinalValue = this.getUsernameService.getUsername()
        .subscribe(username => this.username = username.data[0].AccountName);
        console.log(myFinalValue);
    }
}

Ultimately, my goal is to just assign the value from username.data[0].AccountName to the variable myFinalValue.

Thanks in advance for your help!

Semblance answered 18/10, 2017 at 6:29 Comment(0)
S
3

It turns out that since the observable is asynchronous and as Suren said "callback will work only when it is finished, you don't know when", I needed to initiate the code that was subscribing to the first service in my component ngOnInIt. From there, I needed to pass the subscribe value to the method in the component that actually calls the subscribe form the service as a parameter.

Here's the piece form my component (you can see the this.username value passed to the getCharges() method as getCharges(accountName):

getCharges(accountName) {
  this.getChargesService.getCharges(accountName)
  .subscribe((charges) => {
      this.charges = charges.data;
      }, (error) => console.log(error) 
      )
  }


ngOnInit() {
this.getUsernameService.getUsername()
   .subscribe(username =>  { 
        this.username = username.data[0].AccountName;
        this.getCharges(this.username);
        })
   }

Then in the service file with the getUsernameService.getUsername() service/method, I was easily able to assign the parameter which contained my desired value to a variable.

Hope that helps!

Semblance answered 18/10, 2017 at 19:45 Comment(0)
S
5

Because your call is an asynchronous (callback will work only when it is finished, you don't know when), you can't return a value from the asynchronous call, so you need only to assign it when the call is finished. You need to do your logic which is related to the username you get in the subscribe method. You need to create a field to keep the value of the username for the later use in the class.

@Injectable()
export class AnotherService {

    username: any[] = [];
    myFinalValue: string;

    constructor(private getUsernameService: UsernameService) { }

    someMethod() {
        this.getUsernameService.getUsername()
        .subscribe(username => this.myFinalValue = username.data[0].AccountName));
    }
}
Sophronia answered 18/10, 2017 at 6:30 Comment(5)
OP might also try to use username.json() or username.text()Classmate
That solution is returning undefined.Semblance
Use myFinalValue only with binding, you can't know when it will be returnedSophronia
Thanks for your input Suren, but I need the value from the observable to use in a service, not in a component/html template. Is there a way to do binding inside a service as opposed to an html page?Semblance
You know it will be better to understand observables at all and then try to do something. reactivex.io/rxjs See the basics and look at the methods. Maybe you can think out how to make your logicSophronia
S
3

It turns out that since the observable is asynchronous and as Suren said "callback will work only when it is finished, you don't know when", I needed to initiate the code that was subscribing to the first service in my component ngOnInIt. From there, I needed to pass the subscribe value to the method in the component that actually calls the subscribe form the service as a parameter.

Here's the piece form my component (you can see the this.username value passed to the getCharges() method as getCharges(accountName):

getCharges(accountName) {
  this.getChargesService.getCharges(accountName)
  .subscribe((charges) => {
      this.charges = charges.data;
      }, (error) => console.log(error) 
      )
  }


ngOnInit() {
this.getUsernameService.getUsername()
   .subscribe(username =>  { 
        this.username = username.data[0].AccountName;
        this.getCharges(this.username);
        })
   }

Then in the service file with the getUsernameService.getUsername() service/method, I was easily able to assign the parameter which contained my desired value to a variable.

Hope that helps!

Semblance answered 18/10, 2017 at 19:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.