Alex Bryanskiy
Alex Bryanskiy

Reputation: 435

Angular. Get value from subscription inside switchMap

I have user profile editing form. If user upload photo i need to upload it to backend, get picture name in response (timestamp_name.jpg for example) and save this name with other provided properties, such as name, email and so on. In store effect i have tried to do it in next way:

@Effect()
  profileUpdated$ = this.actions$.pipe(
    ofType<ProfileUpdated>(UserActionTypes.ProfileUpdated),
    map(action => action.payload),
    switchMap(payload => {
      if (!!payload.picture) {
        this.uploadResource.image(payload.picture.files[0]).subscribe((res) => payload.picture = res);
      }
      return this.userResource.updateMyself({user: payload});
    }),
  );

But property picture did not changed, cause it inside subscription. Is there another solution to achieve it?

Upvotes: 0

Views: 2449

Answers (1)

Sam Herrmann
Sam Herrmann

Reputation: 6966

You are correct in detecting that the subscribe is the problem. A subscribe should never appear in an operator. Only the end consumer of profileUpdated$ needs to subscribe. Below is a modified version of your code:

profileUpdated$ = this.actions$.pipe(
    ofType<ProfileUpdated>(UserActionTypes.ProfileUpdated),
    map(action => action.payload),
   // Upload image if needed
    switchMap(payload => {
      if (!!payload.picture) {
        return this.uploadResource.image(payload.picture.files[0]).pipe(
          map(res => {
             payload.picture = res;
             return payload;
          })
        );
      } else {
        // A switchMap operator must always return an Observable,
        // so in the case where no image needs to be uploaded
        // we simply return the original payload as an Observable.
        return of(payload);
      }
    }),
    // Update profile information
    switchMap(payload => this.userResource.updateMyself({user: payload}))
  );

Upvotes: 4

Related Questions