Zwracanie Subscribe - dodanie wartości z innego strumenia.

0

Dzień dobry.
Zaczynam przygodę z programowaniem.
Bardzo proszę o pomoc.
Mam dwa Observable :
Pierwszy:

 getItemInfo(): Observable<any[]> {
    return this.db.list<Company_item>(this.API_URL_ITEM).snapshotChanges().pipe(
      map(response => response.map((item) => this.assignKey(item))),
        map(res => res.map(name => this.getCompanyName(name))));
  }

Wyświetla on dane w mat-table. Emituje wartość id, którą wykorzystuję to sprawdzenia drugiego strumienia i wyświetlenia z niego wartości company_name z odpowiedniego obiektu,
drugi strumień to:

 getCompaniesInfo(): Observable<Company[]> {
    return this.db.list<Company>(this.API_URL_COMPANIES).snapshotChanges().pipe(map(response => response.map((item) => this.assignKey(item))));
  }

Mam funkcję sprawdzającą w Observable wartość id obiektu i zwracającą ten obiekt z odpowiednim numerem id:

    getIdInfo(id: string): Observable<Company> {
    return this.getCompaniesInfo().pipe(map(res => res.find(re => re['key'] == id)))
  }
  getIdInfo$(id: string) {
    return  this.getIdInfo(id).subscribe(event => event.company_name
      )
  }

Oraz mam funkcje spread
:

 private assignKey(item) {
    return {...item.payload.val(), key: item.key }
  }
  private getCompanyName(name) {
    return {...name, company: this.getIdInfo$("1") }
  }

Jak zmodyfikuję funkcję to wyświetla mi w konsoli odpowiednią wartość:

  getIdInfo$(id: string) {
    return  this.getIdInfo(id).subscribe(event => console.log(event.company_name)
      )
  }

natomiast jak robię return (tak jak powyżej ) to wyświetla: [object Object]

Bardzo proszę o pomoc, naprowadzenie, wskazówkę. To już X próba, starałem rozebrać to na czynniki pierwsze, stąd tak niejasny kod.

1

Jesus co to za codebase swoją drogą. Konwencja jest taka że $ w zmiennej powinien być jeśli to Observable a nie już odpalony subscribem Observable.

Chciałbym Ci pomóc ale totalnie nie rozumiem o co kaman po tych urywkach. Musiałbym cały kontekst zobaczyć ale jak widzę jak ktoś nazywa funkcje getInfo$ gdzie odpala Observable to mózg mi się przekręca 🤣

0

Po pierwsze - popraw to o czym pisze @rjakubowski.

Po drugie - wyświetlanie [Object object] jest wtedy gdy zwracasz cały obiekt do widoku. Skąd "html" ma wiedzieć co chcesz wyświetlić? Widok nie wyświetli ci całego obiektu póki go nie sformatujesz.

PRZYKŁAD - model

export interface Company {
  id: number;
  name: string;
}

WIDOK

<div>
<h2>MOJA FIRMA</h2>
<p>{{ company.id }}</p>
<p>{{ company.name}} </p>
</div>

Co prawdopodobnie robisz ty to zwracasz cały obiekt {{ company }}

Nawet sam mat-table w przykładzie nie wyświetla całego obiektu, tylko jego pole element.weight

  <!-- Weight Column -->
  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef> Weight </th>
    <td mat-cell *matCellDef="let element"> {{element.weight}} </td>
  </ng-container>
0

Bardzo dziękuję za uwagi.

Poprawiłem, proszę zobaczyć teraz:

//SERWIS

//Pierwszy Observable
 getItemsInfos(): Observable<any[]> {
    return this.db.list<Company_item>(this.API_URL_ITEM).snapshotChanges().pipe(
      map(response => response.map((item) => this.assignKey(item))),
        map(res => res.map(name => ({...name, company: this.getIdInfo$("1").pipe(
          map( res => res.company_name)
        )}))));
  }

  //Drugi Observable
   getCompaniesInfos(): Observable<Company[]> {
    return this.db.list<Company>(this.API_URL_COMPANIES).snapshotChanges().pipe(map(response => response.map((item) => this.assignKey(item))));
  }

  //Strumień (tutaj używam $, bo nie ma subscribe() - tak?)

    getIdInfo$(id: string): Observable<Company> {
    return this.getCompaniesInfos().pipe(map(res => res.find(res => res['key'] == id)))
  }

  //

    private assignKey(item) {
    return {...item.payload.val(), key: item.key }
  }

//Komponent:
 companyItems$: Observable<Company_item[]> = this.companiesService.getItemsInfos();

 displayedColumns: string[] = ['billing_date', 'billing_month', 'billing_us', 'billing_vat', 'billing_worker', 'billing_zus', 'company_id', 'key', 'company' ];

  dataSource = this.companyItems$;

//WIDOK:
<table class="table" mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <ng-container matColumnDef="company">
    <th mat-header-cell *matHeaderCellDef>Nazwa Firmy</th>
    <td mat-cell *matCellDef="let item">{{ item.company }}</td>
  </ng-container>
</table>

WIDOK dla item.company zwraca:

[object Object]

Widok11.PNG

0

Tak, $ leci po nazwie zmiennej która trzyma strumień. W Twoim przypadku item.company musi być obiektem, skoro wyświetla [object object]. Coś będziesz miał schrzanione w tym mapowaniu na moje oko powyżej. Ewentualnie możesz sobie podejrzeć jak wygląda Twoja struktura: na OnInit się subskrybnij do strumienia i lognij w konsolę - będziesz wiedział jak Twoja struktura wygląda i wtedy już podopinasz sobie jak leci wszystko.

0

Właśnie nie wiem jak zwrócić tą nazwę company. Zwraca [object Object]:
zwraca.PNG

Strumienie:
items.PNG
Companies.PNG

1

Twoja zmienna company jest typem observable. Przy mapowaniu wcześniej z observable musisz zwrócić sobie wartość z tego strumienia a nie sam strumień.

0

Zrób zamiast:

<td mat-cell *matCellDef="let item">{{ item.company }}</td>

tymczasowo

<td mat-cell *matCellDef="let item">{{ JSON.company(item.company) }}</td>

I się dowiesz co tam siedzi.

0

@Riddle - nic tam sensownego nie ma niestety.

Próbuję trochę inaczej, chcę zwrócić wartość id ze strumienia, ale jak rozumiem nie synchronizują mi się dane w odpowiednim czasie:

getItemsInfos(): Observable<any[]> {
  return this.db.list<Company_item>(this.API_URL_ITEM).snapshotChanges().pipe(
    map(response => response.map((item) => this.assignKey(item))),
      map(res => res.map(name => ({...name, company: this.getIdInfo("1")
      }))));
}

getCompaniesInfos(): Observable<Company[]> {
  return this.db.list<Company>(this.API_URL_COMPANIES).snapshotChanges().pipe(map(response => response.map((item) => this.assignKey(item))));
}

getIdInfo(id: string): string {
  let companyName: string = "Start";
  const res$ = this.getCompaniesInfos().pipe(map(res => res.find(res => {return res['key'] == id})))
  res$.subscribe(res => companyName = res.company_name)
  return companyName;
}
  • getIdInfo bez zainicjowania comapnyName otrzymuje wartość undefined, natomiast w tym przypadku w ngOnInit() oraz w widoku otrzymuję wartość inicjalizacyjną - "Start" ( nie przypisuje mi res.company_name)
rjakubowski napisał(a):

Twoja zmienna company jest typem observable. Przy mapowaniu wcześniej z observable musisz zwrócić sobie wartość z tego strumienia a nie sam strumień.

Tak, ale jak rozumiem mat-table dataSource sam odpala strumień (nie może dostać już z subscribe)?

0

Chyba niepotrzebnie skomplikowałem wszystko.
Skorzystałem z operatora combineLatest i za pomocą find zwróciłem odpowiednią nazwę dla odpowiedniego id. Wszystko po stronie JS. Po stronie widoku dobiłem się już do odpowiedniej wartości za pomocą item.companyData.company_name.

Bardzo dziękuję za zaangażowanie, bez pomocy by się nie udało.

1 użytkowników online, w tym zalogowanych: 0, gości: 1