Thomas Schneiter
Thomas Schneiter

Reputation: 1153

Rxjs map to array of strings returns undefined

I'm trying to use rxjs map to get an array of strings from a response. The response is an array of objects with guid and name property.

When i get the full response:

public getAllSolutions(): Observable<string[]> {
  return this.http.get(`${this.baseUrl}/Solution/All`)
    .map((results: Response) => results.json())
}

and output it using:

this.solutionsService.getAllSolutions().subscribe(
    data => {
      console.log(data);
    }
);

i get this:

[
{guid:"6e3d4646e1ad6d78bd225d2bdb5a14709c12e8280796a3b4f27536e8aaaf89ed", name: "Solution 1"},
{guid: "737f838cc457d833ff1dc01980aa56e9661304a26e33885defe995487e3306e7", name: "Solution 2"}
]

What i would like to have is an array just containing name

Following documentation this should work:

public getAllSolutions(): Observable<string[]> {
  return this.http.get(`${this.baseUrl}/Solution/All`)
    .map((results: Response) => results.json())
    .map(solutions => solutions.name);
}

but the output i get is undefined. What am i doing wrong here?

Upvotes: 0

Views: 3852

Answers (1)

th3n3wguy
th3n3wguy

Reputation: 3747

Let me give you a fully-corrected example because your return value isn't even defined properly for the values you are giving, even though it is what you are expecting. Here is a corrected version of your code:

/* This is your response example from your API (as per your comments) that is generated when you run the response.json() function in the Observable mapper:
 *
 * [
 *   {guid:"6e3d4646e1ad6d78bd225d2bdb5a14709c12e8280796a3b4f27536e8aaaf89ed", name: "Solution 1"},
 *   {guid: "737f838cc457d833ff1dc01980aa56e9661304a26e33885defe995487e3306e7", name: "Solution 2"}
 * ]
 */

// Define this interface outside of your class to make it easier to reason in your code, regardless of the function below that you choose. You can even put this interface into a different file, if you wish to do so.
interface Solution {
  guid: string;
  name: string;
}
 
// This should be the function, assuming RxJS (v4) and @angular HttpModule (v2-4):

public getAllSolutions(): Observable<string[]> {
  return this.http.get(`${this.baseUrl}/Solution/All`)
    .map((results: Response) => <Solution[]>results.json())
    .map((solutions: Solutions[]) => solutions.map((solution: Solution) => <string>solution.name));
}

// This should be the function, assuming RxJS (v5) and @angular HttpClientModule (v5+ currently):

// You need to import the map function from RxJS or else you will get all kinds of stupid errors that don't actually tell you that you need to include this function. This import is also case-sensitive. Fun times.
include { map } from 'rxjs/operators';

public getAllSolutions(): Observable<string[]> {
  return this.http.get(`${this.baseUrl}/Solution/All`)
    .pipe(
      map((response: Solution[]) => response.map((solution: Solution) => <string>solution.name))
    );
}
[
{guid:"6e3d4646e1ad6d78bd225d2bdb5a14709c12e8280796a3b4f27536e8aaaf89ed", name: "Solution 1"},
{guid: "737f838cc457d833ff1dc01980aa56e9661304a26e33885defe995487e3306e7", name: "Solution 2"}
]
What i would like to have is an array just containing name

Following documentation this should work:

public getAllSolutions(): Observable<string[]> {
  return this.http.get(`${this.baseUrl}/Solution/All`)
    .map((results: Response) => results.json())
    .map(solutions => solutions.name);
}

Upvotes: 2

Related Questions