16

I'm new to the concepts of observables and need some help with a conversion.
I have a service which returns an Observable<Response> from a Http request, but I need to convert it do an Observable<PriceTag> to use it on a DataSource inside the connect method.
Is there anyway to do this?

This is the method from my service:

getPriceTags(): Observable<Response> {

    // Set the request headers
    const headers = new Headers({ 'Content-Type': 'application/json' });

    // Returns the request observable
    return this.http.post(Constants.WEBSERVICE_ADDRESS + "/priceTag", null, {headers: headers});

}

And here is the DataSource class where I need to return it as an Observable<PriceTag>:

export class PriceTagDataSource extends DataSource<PriceTag> {

    constructor (private priceTagService: PriceTagService) {
        super();
    }

    connect(): Observable<PriceTag> {

        // Here I retrieve the Observable<Response> from my service
        const respObs = this.priceTagService.getPriceTags();

        // Now I need to return a Observable<PriceTag> 

    }

    disconnect() {}

}

Here's an example from the response from my request:

{
    // This object is used to check if the query on the server was sucessful
    "query": {
        "sucessful": true
    },

    // These are my PriceTags 
    "tags": [
        {
            "id": "1",
            "name": "MAIN"
        },
        {
            "id": "2",
            "name": "CARD"
        }
    ]
}
1
  • Did one of the answers help you? Commented Aug 28, 2017 at 13:11

3 Answers 3

35

As of angular 4.3 this can be done automatically.

Example:

export class SomeService {
    constructor(private http: HttpClient) {}  // <--- NOTE: HttpClient instead of Http

    getSome(): Observable<MyAwesomeObject> {
        return this.http.get<MyAwesomeObject>('myUrl');
    }
}

So in your case that would be:

return this.http.post<PriceTag>(Constants.WEBSERVICE_ADDRESS + "/priceTag", null, {headers: headers});

Again, use the HttpClient instead of Http

Sign up to request clarification or add additional context in comments.

6 Comments

Ooooh i didn't know it could do that... neat
is there a difference between that and getSome(): Observable<MyAwesomeObject> { return this.http.get('myUrl').map((response) => <MyAwesomeObject>response.json()); }
For me this doesn't actually create the PriceTag object. The data is still of type Object.
Hi, I have a small question. There is something I do not understand, in this solution I indeed can get all properties of instance of MyAwsomeObject but in case thic class would also have some public method I am not able to access it - so it looks like json representation of MyAwsomeObject - not instance of it itself. Am I doing something wrong?
Ok.. I found an answer to my comment. stackoverflow.com/questions/48102824/…
|
5

I guess your HTTP Response is a JSON containing a PriceTag? The issue is that you want to create a PriceTag object. You can just convert the json to a PriceTag by type casting, but then it won't be a real PriceTag object.

The way we have resolved this is:

export class Serializable {
  constructor(json?: any) {
    if (json) {
      Object.assign(this, json);
    }
  }
}

And then a serializable class:

export class PriceTag extends Serializable {}

Then, your GetPriceTags function needs to be changed to:

getPriceTags(): Observable<PriceTag> {

    // Set the request headers
    const headers = new Headers({ 'Content-Type': 'application/json' });

    // Returns the request observable
    return this.http.post(Constants.WEBSERVICE_ADDRESS + "/priceTag", null, {headers: headers})
    .map(res => new PriceTag(res.json()));

}

Comments

1

In the Angular 4+, It can be done automatically. You can change your getPriceTags method:

export class PriceTagService {
    constructor(private http: HttpClient) {}

    getPriceTags<T>(): Observable<T> {

        // Set the request headers
        const headers = new Headers({ 'Content-Type': 'application/json' });

        // Returns the request observable
        return this.http.post<T>(`${Constants.WEBSERVICE_ADDRESS}/priceTag`, null, {headers: headers});

    }
}

And your DataSource class can be:

export class PriceTagDataSource extends DataSource<PriceTag> {
    constructor (private priceTagService: PriceTagService) {
        super();
    }

    connect(): Observable<PriceTag> {
        // Here you can retrieve the Observable<PriceTag> from service and return directly
        return this.priceTagService.getPriceTags<PriceTag>();
    }

    disconnect() {}
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.