GeForce RTX 4090
GeForce RTX 4090

Reputation: 3508

Subscribe to a nested observable

Let's say I have a function in a provider:

saveCar(car: Car) {
    return this.saveCarImages(car).subscribe(
      (data:any) => {
        if(data[0].seats){
          car=data[0];
      }
      return this.api.put(`/car/${car.id}`, car, {
        headers: {
          'Content-Type': 'application/json'
        }
      });
      }
    )
  }

And this helper function in the provider that has to be executed before the actual car is saved:

 saveCarImages(car: Car) {
    return Observable.create((observable) => {
      let fileSaver = this.injector.get(FileSaverProvider);
    let promisearr = [];
        promisearr.push(Observable.create((observable) => {
          fileSaver.uploadImage(car.helpImage.file).subscribe(
            (data: any) => {
              car.helpImageId = data.id;
              observable.complete(car);
            }
          )
        })
        )
            promisearr.push(Observable.create((observable) => {
              fileSaver.uploadImage(car.helpImage2.file).subscribe(
                (data: any) => {
                  car.helpImageId2 = data.id;
                  observable.complete(car);
                }
              )
              }));
    return Observable.forkJoin(promisearr);
    });
  }

And then I have this code in a TS file of a component:

        this.provider.saveCar(this.car).subscribe(
            (response: any) => {
                if (response) {
                       //success
                }
            },
            (error: any) => {
                      //error
            }
        );

But this is not working. What Im trying to achieve here is subscribing to this.api.put(car) from the TS file of the component, but I need the car images to be uploaded first, therefore the this.api.put(car) is nested inside the saveImages observable. How can I subscribe to the this.api.put(car) from the TS file of the component?

Upvotes: 0

Views: 189

Answers (1)

Picci
Picci

Reputation: 17762

You do not need to use Observable.create method. That is a pretty low level way to create Observables, which you normally do not need to use.

Specifically, looking at you code, you could look if this version of the helper method works

saveCarImages(car: Car) {
    const fileSaver = this.injector.get(FileSaverProvider);
    const obsArray = [];
    obsArray.push(fileSaver.uploadImage(car.helpImage.file).pipe(map(id => {
       car.helpImageId = id;
       return car;
    })));
    obsArray.push(fileSaver.uploadImage(car.helpImage2.file).pipe(map(id => {
       car.helpImageId2 = id;
       return car
    })));
    return forkJoin(obsArray);
  }

Then saveCar would become

saveCar(car: Car) {
   return this.saveCarImages(car).pipe(
     map(data => data[0]),
     switchMap(car => this.api.put(`/car/${car.id}`, car, {
        headers: {
          'Content-Type': 'application/json'
        }
      })
    )
  }

At this point your component should be able to call saveCar and subscribe to it.

Upvotes: 2

Related Questions