Home > Mobile >  What is wrong with my Angular 13 Subscribe?
What is wrong with my Angular 13 Subscribe?

Time:10-12

I've been fighting this thing all night, and can't figure out what I'm doing wrong. I've tried lots of different things, but haven't been successful yet. I'm using Angular 13. Here is my NetworkService:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map, ReplaySubject } from 'rxjs';
import { environment } from 'src/environments/environment';
import { Inputs } from '../_models/Inputs';

@Injectable({
  providedIn: 'root'
})
export class NetworkService {
  private networkSource = new ReplaySubject<any>();
  Network$ = this.networkSource.asObservable();
  network: any;
  private helloSource = new ReplaySubject<any>();
  Hello$ = this.helloSource.asObservable();
  hello: any;

  constructor(private http: HttpClient) { }

  getNetworkInfo(inputs: Inputs) {
    var date = inputs.FillDate.toISOString().split('T')[0];
    var url = `/price/pricenetworkinfo/?testMode=true&priceNetworkName=${inputs.PriceNetworkName}&fillDate=${date}`;

    return this.http.get(`${environment.baseApiUrl}${url}`)
      .pipe(map((response: any) => {
        this.network = response;
        this.networkSource.next(this.network);
      }));
  }
}

Here is the method that calls it:

  getData() {
    this.networkService.getNetworkInfo(this.model)
      .subscribe(x => {
        this.networkInfo = x;
      }).add(() => {
        console.log(JSON.stringify(this.networkInfo));
      });

    this.enumService.getEnums()
      .subscribe(x => {
        this.enums = x;
        console.log(JSON.stringify(this.enums));
      });
  }

Now.... The call to getEnums works when it is in the ngOnInit function, but not in this function (this function is called by a button click). And the getNetworkInfo call doesn't work here, but I can't move it to the ngOnInit function because it requires input before being called.

The two services both work, fetching the requested data when called, but the calling component does not get that data back. I can see it in the dev tools, but stepping through, the x in the subscribe method is undefined.

I have another project where I'm doing pretty much the same thing (different services, but set up the same way), and that project works fine. This one, though, I have to be missing something really stupid. Any help is appreciated.

EDIT: Adding the enum service and button template as requested below:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map, ReplaySubject } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root'
})
export class EnumService {
  private enumSource = new ReplaySubject<any>();
  Enums$ = this.enumSource.asObservable();
  enums: any;

  constructor(private http: HttpClient) { }

  getEnums() {
    let enums = sessionStorage.getItem('Enums');
    if (!enums) {
      return this.http.get(environment.baseApiUrl   '/utility/getuienums')
        .pipe(map((response: any) => {
          this.enums = response;
          this.enumSource.next(this.enums);
          sessionStorage.setItem('Enums', JSON.stringify(this.enums));
        }))
    }
    else {
      this.enumSource.next(JSON.parse(enums));
      return this.Enums$;
    }
  }
}
<div >
              <button 
                      (click)="getData()">Send</button>
       </div>

Note that with the enums I'm saving them to session storage, because they will be reused as people use the site (this is an application people within our company use). I do note that now that I've changed map to tap as suggested in the offered answer, I do get results back from the NetworkService, and I do not have logged output from the EnumService. I'll have to look into the tap function, as I'd never seen it before.

CodePudding user response:

You getNetworkInfo function returns an observable that does not emit any data. The reason is that you do not return anything from map method. Try to change the operator to tap in order to perform side effects (like you did) without changing the emitted values.

return this.http.get(`${environment.baseApiUrl}${url}`)
  .pipe(tap((response: any) => {
    this.network = response;
    this.networkSource.next(this.network);
}));
  • Related