#How to show html element after successful HTTP request?

31 messages · Page 1 of 1 (latest)

lunar halo
#

How to show this message on successfull request? Do I need to create behavior subject or signal and set it to true?

<p-message i18n closable severity="success" [life]="10000"
  >Your item is under our review, soon will be published.</p-message
>
  readonly addItem$ = new Subject<CreateItemDto>();
  addItem(item: CreateItemDto): Observable<CreatedItemDto> {
    return this.#http
      .post<OperationResultsOfCreatedItemDto>(
        this.#commonApi.client.items.toPostRequestInformation({}).URL,
        item
      )
      .pipe(map((q) => q?.data ?? {}));
  }
split salmon
#
success = signal(false);

createItem() {
  this.service.addItem(...).subscribe(() => this.success.set(true));
}

for example.

lunar halo
#

How about

Message page

@if (itemsService.addItemSuccess$ | async) {
<p-message i18n closable severity="success" [life]="10000"
  >Your item is under our review, soon will be published.</p-message
>
}
  ngOnDestroy(): void {
    this.itemsService.addItemSuccess$.next(false);
  }

Items service

  readonly addItem$ = new Subject<CreateItemDto>();
  readonly addItemSuccess$ = new BehaviorSubject<boolean>(false);
  addItem(item: CreateItemDto): Observable<CreatedItemDto> {
    return this.#http
      .post<OperationResultsOfCreatedItemDto>(
        this.#commonApi.client.items.toPostRequestInformation({}).URL,
        item
      )
      .pipe(
        map((q) => q?.data ?? {}),
        tap(() => this.addItemSuccess$.next(true))
      );
  }
lunar halo
#

Or instead of ng destroy I can use (onClose)="itemsService.addItemSuccess$.next(false)"
on message component

#

But still is it good solution?

split salmon
#

Ah, so you seem to want to display a toast. This indeed is usually done by calling a service, and by displaying the toast component from the root component, so that they can be displayed whatever the page is.

lunar halo
split salmon
#

The best way, IMHO, would be to use a toast component, displayed from the root component, and gettings its messages from a service.
That way each component that you happen to redirect to after performing a successful operation doesn't have to care about displaying the success message that is not its concern.
But the principle is the same either way: share a service between the "message" component (which reads the messages to display) and the "form" component (which adds a success message to display).

lunar halo
split salmon
#

A signal always has a value. toSignal takes an observable as argument, subscribes to it, and returns a signal that contains the last value emitted by the observable. But it always has a value. So, what value can it possibly have before the observable has emitted its first value? undefined, of course.

lunar halo
#

Yeah but when my value is emitted it still shows undefined when console log from subscription shows real value

split salmon
#

No. The effect shows undefined right after the service has been instantiated because the effect always runs once, and reads the value of the signal at that time, which is undefined. Then it logs the new value of the signal when it changes, i.e. after the first emission of the observable.

lunar halo
#
sell.ts:41:63
undefined sell.ts:43:15
#

So I cant use to signal right here? I need to use async pipe?

#

I still don't understand why effect is not showing emitted value

split salmon
lunar halo
split salmon
#

When I navigate to /add-item and click the button, all I see in the console is undefined, which is expected since the sell component subscribes (directly and via toSignal) to a Subject, so it waits for the next message to come, and the effect shows the current value of the signal, which is undefined.

lunar halo
#

So how do I console log the message?

#

Because I’m not sure

split salmon
#

You could use a BehaviorSubject or a ReplaySubject instead of a Subject. Or a Signal. Or you could display the messages from the root component, which always exists, and thus subscribes to the subject before any component ever posts a message.

lunar halo
#

Is that solution okey?

split salmon
#

Have you tested it? Does it do what you want it to do?

lunar halo
#

Yeah it does

#

I'm just wondering about this on destroy

split salmon
#

Notes though:

  • There is an `asReadonly() method to turn a writable signal into a non-writable one
  • ToastMessageOptions seems to actually be a message, not just options., so I'd rename it.
  • I still find it really strange to display messages from the component where you redirect.
  • What if that component needs to post its own messages? It will destroy them on destroy...
  • I would avoid ngOnDestroy and instead inject the DestroyRef and use it in the constructor.
lunar halo
#

Maybe that will make more sense

split salmon