1
votes

I'm trying to implement a CRUD functionality in a reactive programming way. I have a form where one of it's field identifier_name must be unique.

But, before calling the create new or update method, I need to check first if the value of identifier_name field that I'm creating or updating is already exists in the observable where my observable is like this.

this.userService.users$;

Below is my code in my component.

@Component({...})
    export class UserEditComponent implements OnInit, OnDestroy {

        subscription: Subscription = new Subscription();

        ngOnDestroy() {
          this.subscription.unsubscribe();
        }

        saveUser(): void {
            if (this.userForm.valid) {
                this.identifierExists$.subscribe(exists => {
                      if (exists) {
                        this.snackBar.open('The scope identifier must be unique.', 'Close', { duration: 5000 });
                      } else {
                        if (this.isNewRecord) {
                            this.createNewUser();
                        } else {
                            this.updateUser();
                        }
                      }
                    })          
            } else {
                this.snackBar.open("An error occured while saving your changes. Please try again.", "Close", { duration: 5000 });
            }
        }

      createNewUser(): void {
        this.subscription.add(
          this.userService.saveUser(this.userForm.value)
            .pipe(catchError(this.handleError))
            .subscribe(() => {
              this.snackBar.open('New user successfully created.', 'Close', { duration: 5000 });
            })
        )
      }

      updateUser(): void {
        this.subscription.add(
          this.userService.selectedUserIdAction$
            .pipe(
              switchMap(id => this.userService.updateUser(id, this.userForm.value))
            )
            .subscribe(_ => {
              this.snackBar.open("User successfully updated.", "Close", { duration: 5000 })
            })
        )
      }

    }

What I have in mind is to do like this.

    private identifierSubject = new BehaviorSubject<string>('');
    identifierAction$ = this.identifierSubject.asObservable();

    identifierExists$ = this.identifierAction$.pipe(
            switchMap(identifier => {
                this.userService.users$
                    .pipe(
                        map(users => users.some(user => user.identifier_name === identifier))
                    )
            })
        )

I'm not sure if this is the correct way to achieve my requirement as I'm very new in the concept of reactive programming.

Additionally, if you noticed my 2 methods createNewUser() and updateUser. Is there a way I can trigger the create and update without subscribing? What I know in reactive programming was to avoid the subscribe. But, not really sure how to do this the right way.

Hope you can guide me on how to properly do this in a reactive programming way.

TIA

1

1 Answers

0
votes
  1. You say you have a form and you want a value to be unique. I highly recommend that you don't do this check when pressing on saveUser(). Rather use validators, as a result the form won't be valid until you have a unique name. Reactive forms serve both - sync and async - validators.
  2. Are you aware, that you add a subscription to your component with every submit click?
  3. I have trouble to understand why your identifier is stored within a BehaviorSubject. Isn't that too much?

Regarding your create+update check out this post: Angular http.post without .subscribe callback