'Function with RxJS and combineLatest sometimes works and sometimes doesn't

If you call this function multiple times with the values of the observables obs1 and obs2 being the same each time, the returned array is not always the same.

getProductosUnicos(obs1: Observable<any>, obs2: Observable<any>): Observable<any> {
    return combineLatest([obs1, obs2])
    .pipe(
      map(([prod1, prod2]) => {
          return prod1.find((prod: any) => prod1.NombreProducto === prod2)
      }),
      toArray(),
      tap( a => console.log(a.length))
    )
}

What I'm trying to get are the objects from obs1 whose NombreProducto matches the strings coming from obs2.

As Liam ask me I add more code so that it is better understood:

  // component.ts
  
  getProductos() {
    this._gasolinerasService.getProductosUnicos(
      this._gasolinerasService.getProductos(),
      this._gasolinerasService.getProductosMunicipio(this.idMunicipio)
      ).subscribe( (data: any) => {
        this.productos = data
        if(!this.default) {
          if (this.idProducto == '') {
            this.idProducto = data[0].IDProducto;
            this.producto = data[0].NombreProducto;
        }
      }
      this.getGasolineras();
    })
  }


  // service.ts

  baseUrlGasolinerasMunicipio = "https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes/EstacionesTerrestres/FiltroMunicipio/";
  baseUrlProductos = "https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes/Listados/ProductosPetroliferos/";


  getProductos(): Observable<any> {
    return this._httpClient.get<Producto[]>(this.baseUrlProductos)
  }


  getProductosMunicipio(idMunicipio: string): Observable<any> {
    return this._httpClient.get<Gasolinera[]>(this.baseUrlGasolinerasMunicipio + idMunicipio).pipe(
      map((data: any) => data.ListaEESSPrecio.map((data: any) =>
        ({
          "Biodiésel": data["Precio Biodiesel"],
          "Bioetanol": data["Precio Bioetanol"],
          "Gas natural comprimido": data["Precio Gas Natural Comprimido"],
          "Gas natural licuado": data["Precio Gas Natural Licuado"],
          "Gases licuados del petróleo": data["Precio Gases licuados del petróleo"],
          "Gasóleo A habitual": data["Precio Gasoleo A"],
          "Gasóleo B": data["Precio Gasoleo B"],
          //"Gasóleo C": data["Precio Gasoleo C"],
          "Gasóleo Premium": data["Precio Gasoleo Premium"],
          "Gasolina 95 E10": data["Precio Gasolina 95 E10"],
          "Gasolina 95 E5": data["Precio Gasolina 95 E5"],
          "Gasolina 95 E5 Premium": data["Precio Gasolina 95 E5 Premium"],
          "Gasolina 98 E10": data["Precio Gasolina 98 E10"],
          "Gasolina 98 E5": data["Precio Gasolina 98 E5"],
        })
      )),
      concatMap(from),
      map(gasolinera => Object.keys(gasolinera).filter(k => gasolinera[k] !== '')),
      reduce((acc: string[], item: string[]) => acc.concat(item)),
      map(data => data.filter((item: string, index: number) => data.indexOf(item) === index)),
      map(data => data.sort((a: any, b: any) => b.localeCompare(a))),
      concatMap(from),
    );
  }



  getProductosUnicos(obs1: Observable<any>, obs2: Observable<any>): Observable<any> {
    return combineLatest([obs1, obs2])
    .pipe(
      map(([productos, prodGasolinera]) => {
          return productos.find((prod: any) => prod.NombreProducto === prodGasolinera)
        }),
        toArray(),
        tap( a => console.log("sdsf " + a.length))
      )
  }


Solution 1:[1]

I finally resolved it. concatMap(from) emits at once so combineLatest not always works as expected. I resolved with concatMap(a => from(a).pipe(delay(1))). Thank you all for your effort.

Solution 2:[2]

Try changing your component code like this and see if this helps. Basically, you store the observables in private variables and then pass that to the combine latest within the service.

export class MyComponent {
    ...
    idMunicipio = "";
    private productos$ = this.productoService.getProductos();
    private productosMunicipio$ = this.productoService.getProductosMunicipio(this.idMunicipio);
    
    ...
    
    // Use the observable variables in the getProductos() call 
    getProductos() {
        this._gasolinerasService.getProductosUnicos(this.productos$, this.productosMunicipio$)
            .subscribe( (data: any) => {
                this.productos = data
                if(!this.default) {
                    if (this.idProducto == '') {
                        this.idProducto = data[0].IDProducto;
                        this.producto = data[0].NombreProducto;
                    }
                }
          this.getGasolineras();
        });
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Sharath