0

I have this interface with nested array inside:

import { IEmitente } from './ICustomer';

export interface IAccounts {
        current_page: number;
        data: ICustomer[];
        first_page_url: string;
        from: number;
        last_page: number;
        last_page_url: string;
        next_page_url: string;
        path: string;
        per_page: number;
        prev_page_url: string;
        to: number;
        total: number;
}

the customer interface is like this:

export interface ICustomer {
id: number;
name: string;
federalId: string;
firstBuy: date;
balance: number;
}

I have this http get method on service:

getContas(identific,search,page?): Observable<IAccounts[]> {
    return this.httpClient.get<IAccounts[]>(`${this.BASE_URL}/getContas?identific=${identific}&search=${search}&page=${page}`)
  }

the observable is look like this:

{current_page: 1, data: Array(15), first_page_url: "https://web.gruposol.com.br/endpoint/api/getContas?page=1", from: 1, last_page: 19, …}
current_page: 1
data: (15) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
first_page_url: "https://address/api/getContas?page=1"
from: 1
last_page: 19
last_page_url: "https://address/api/getContas?page=19"
next_page_url: "https://address/api/getContas?page=2"
path: "https://address/api/getContas"
per_page: 15
prev_page_url: null
to: 15
total: 275
__proto__: Object

how can I get only data (customers) part from observable using rxjs? I need some like this: on a variable customers:ICustomer[] = []; I'd like to receive only data array from observable. How can I do that? currently my ngOnInit method is like this:

  ngOnInit() {
     this.AlvosService.getContas(this.identific, this.search)
       .subscribe((response) => { console.log(response)} ),
        (error) => { console.log(error); };

  }

3 Answers 3

1

You can use a Pipe, and Map nested values

this.AlvosService.getContas(this.identific, this.search)
          .pipe(
            switchMap((accounts) => accounts.map((account) => account.data))
          )
          .subscribe((customers) => { console.log(customers) }),
          (error) => { console.log(error); }

Note: you better not use variables starting with Capital letters, as in AlvosService, that is bad practice

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

9 Comments

I already tryed this, but once I refer accounts.data I receive this error: Property 'data' does not exist on type 'IAccounts[]
i'm sorry pressed the enter to soon: Property 'data' does not exist on type 'IAccounts[]
@HeberPaesFomin Sorry, my bad, I corrected my answer, should work now
I hope you don't bother with my ignorance, but, you started with this.accounts. it means I have to put your suggested code on subscribe after assignment of this.accounts?
the way you suggested before, the error only appear on compiling process, but on chrome's console shows only what I need, besides the error.
|
0

Try this:

this.AlvosService.getContas(this.identific, this.search)
          .pipe(
            mergeMap(accounts => accounts),
            map((account: IAccounts) => account.data),
            toArray()
          )
          .subscribe((customers) => { console.log(customers)} ),
           (error) => { console.log(error); };

Since your http call is returning an array of IAccounts, you'll need to flatten the array, map the data and zip it into an array again.

2 Comments

with this way I got this error: ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
Sounds fishy. Try with mergeMap((accounts => of(accounts))
0

I figuered out what the error was. If you look the response above you'll see that the response object was not an array. The problem was the brackets on get method on service. Instead of <IAccounts[]> should be <IAccounts> only. So, changed the method like this:

getContas(identific,search,page?): Observable<IAccounts> {
    return this.httpClient.get<IAccounts>(`${this.BASE_URL}/getContas?identific=${identific}&search=${search}&page=${page}`)
  }

It works! thanks so much for your helps.

2 Comments

First I am happy you figured it out (: Second, correct me if I am wrong, buf the error has nothing to do with your first question. The question was how to get a nested array, and the answer was correct. The type interface typo is a different issue. Calling a function “getContacts” that returns a single contact is really strange.
You are not wrong. Your first answer was perfect. I used that. But like I told, was a compile error because the type was wrong. Thank you very much for your help. The getContacts doesn't receive a single contact, but the api wraps the data collection with paginate information, so, I receive an object only with an array inside with data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.