Angular does not wait for the backend service call response in tap

Does anyone have a solution for subscribing to responses when the tap operator is used in a service?

edit(status) {
    dataObj.val = status;
    // call post service with status..
    this.service
        .update(dataObj)
        .pipe(takeUntil(this._ngUnsubscribe$))
        .subscribe(() => {
            //i would like to wait until response come from backend and then navigate to the page so i                get data over there.
            if (res.status === 'Success') {
                this.router
                    .navigate(['../../success'], {
                        relativeTo: this.route,
                    })
                    .then(() => {});
            } else {
                this.location.back();
            }
        });
}

//akita store service

update(
    obj: any,
): Observable < any > {
    return this.service.update(obj).pipe(
        delay(800),
        map((data: RestfulResponse < any > ) => data.data),
        tap((data: anny) => {
            this.store.update((state) => {
                state.updateValue = data; // value is not updating and it is navigating to route
            });
        }),
    );
}

//post service

update(obj){
//post call
}

Any suggestions on utilizing tap in the service side and subscribing on the component side?

I'm aware of using finalize but it doesn't seem to be helpful for adding conditions inside.

Answer №1

Utilizing the tap operator is intended for managing side effects that occur outside of your observable pipeline's scope. This implies that your pipeline will not wait for outcomes from the tap operation itself. It is advisable to reserve its usage primarily for debugging purposes.

If awaiting a specific state change, it is recommended to set up a distinct observable that monitors and selects the desired state alteration within your store.

For triggering supplementary actions in response to certain events, employing ngrx Effects is advised.

To delve deeper into this topic, refer to my post where I elaborate on implementing a similar scenario:

In lieu of directly updating the store, focus on establishing reducers responsible for applying state modifications.

View each of the following tasks as discrete entities that can be implemented autonomously:

  1. Upon user editing, initiate an edit action.
  2. The reducer should update the state consequent to the edit action (e.g., indicating an ongoing save).
  3. Following the edit action trigger, prompt an effect to conduct an HTTP request for saving changes and subsequently signaling a completion action.
  4. Upon completion of the save process, instigate router navigation.

This modular approach enables you to test and validate individual components with ease.

If #1 triggers an action consumed by your reducer (#2), consider setting up an ngrx Effect for #3, which listens for the same action, manages the HTTP call through switchMap, and then cues another action upon completion.

Edit

Here's a straightforward illustration. When the initial APP_LOADED action (initiated from AppComponent) is activated, this Effect initiates an HTTP call to retrieve data from the server and proceeds to trigger an action leveraging the received data as the action payload.

The actual HTTP communication is delegated to another service, the HttpMyConfigDataService, which simply utilizes HttpClient and returns an Observable.

@Injectable({
  providedIn: 'root'
})
export class LoadMyConfigEffect {
  constructor(
    private httpMyConfigDataService: HttpMyConfigDataService,
    private action$: Actions
  ) {
  }

  loadMyConfigData$ = createEffect(() => {
    return this.action$.pipe(
      filter((action) => action.type === 'APP_LOADED'),
      take(1),
      switchMap(() => this.httpMyConfigDataService.get().pipe(
        map(data => {
          return {type: 'MY_CONFIG_DATA_LOADED', payload: data};
        }),
        catchError(err => {
          console.error('Error loading config data.', err);
          return of({type: 'CONFIG_LOAD_ERROR', payload: err.message, isError: true);
        })
      ))
    );
  });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Oops! Looks like there was an error: $http is not defined

I'm facing a challenge with implementing $http in the AngularJS framework. I've gone through various other resources on this issue, but I can't seem to figure out what I'm doing incorrectly. Any assistance would be highly appreciated. T ...

The Angular 11 library module has been successfully imported into the consuming app but it is not being utilized

Currently, I am in the process of creating an Angular library that will encompass services, pipes, and directives to be utilized across various Angular projects within my organization. At this point, I have successfully implemented three services within th ...

Issue with redirecting to another link in Angular routing

After numerous attempts, I finally managed to configure the adviceRouterModule correctly. Despite extensive research and Google searches, I couldn't quite crack it. Here is the configuration for my AdviceRoutingModule: const adviceRouters: Routes = ...

Encountering problem with rendering the header in the footer within a customized package built on react

I am currently working on creating a node package that consists of simple HTML elements. The package is named fmg_test_header. These are the files included in the package: header.jsx index.js package.json header.js function Header() { return "< ...

When using ngClass and the has-error class on load, the class will still be loaded even if the expression evaluates

When attempting to load the has-error class from Bootstrap using ng-class with a condition on a variable injected to the controller from my factory, I encounter an issue where even though the initial value of the variable is false, the has-error class load ...

Getting an error message like "npm ERR! code ENOTFOUND" when trying to install Angular CLI using the command "

Currently, I am eager to learn Angular and have already installed Node version 18.13.0. However, when attempting to install Angular CLI using the command npm install -g @angular/cli, I encountered an issue: npm ERR! code ENOTFOUND' 'npm ERR! sys ...

Verify if JavaScript is enabled on the browser and show a notification if it is not using a custom ASP control

I am currently working with a combination of Javascript, ASP.net, and C# for my project. My goal is to create a custom control that checks if Javascript is enabled in the user's browser and displays a message accordingly. Here is the approach I have t ...

Exploring Child Types in Typescript and JSX minus the React framework

It seems like there's a missing piece of the puzzle that I can't quite figure out. Despite going through the documentation on JSX in non-React settings, I'm still unable to spot my mistake. Let's examine the following code: /** @jsx pra ...

javascript mysql and php clash when it comes to loading

I am encountering an issue where I cannot fetch data from my phpMyAdmin database using php code when loading the map api that utilizes javascript. Currently, only the map javascript is being loaded. I have valuable data stored in my database and any assis ...

Is there a way to position one DIV behind another?

Hey, I'm working on my first project and running into some trouble with divs. I'm trying to position the firework behind the central text but can't figure it out. Can anyone lend a hand? I need to add more details in order to submit the que ...

Removing the JavaScript unicode character 8206 from a text string

I recently transitioned from VB.NET to JavaScript, and I am still getting familiar with the language. I have encountered an issue where a string I'm working with in JavaScript contains Unicode escape characters (0x5206, left-to-right mark) that I need ...

Tips for effectively monitoring scope for data loading

I have successfully created a custom Angular directive that utilizes D3.js to create a visualization. In my HTML, I reference this directive as follows: <gm-link-analysis data="linkAnalysis.connections"></gm-link-analysis> The relevant part o ...

The React Native File generator

Currently, we are utilizing redux actions in our web project. In an effort to share logic between web and native applications, we have integrated these actions into our react native project with the intention of only having to modify the components. One o ...

Exploring a utility function for saving object information in a dynamic state

Imagine my state was structured like this: state = { customer: { name: { elementType: "input", elementConfig: { type: "text", placeholder: "Your Name" }, value: "" }, street: { e ...

The $().bind function will not function properly unless the document is fully loaded

Do I need to include $(document).ready() with $().bind? Here is the HTML portion: <head> <script type="text/javascript" src="jquery-1.10.2.min.js"></script> <script type="text/javascript" src=&quo ...

Occasional TypeError when receiving JSONP response using jQuery .ajax()

Occasionally, I encounter an error message stating Uncaught TypeError: undefined is not a function when processing the JSONP response from my jQuery .ajax() call. The JSON is returned successfully, but sometimes this error occurs during the reading process ...

I am encountering an issue with an undefined variable called "stripe" in my Angular project, despite the fact

Within my stripecreditcardcomponent.html file: <script src="https://js.stripe.com/v3/"></script> <script type="text/javascript"> const payment = Stripe('removed secret key'); const formElements = paymen ...

Unlock the power of jQuery chaining with the val() method

My selected background color is set to: var _back = "#FF0000"; Why doesn't this code change the input field's background color: $("#input").val( _back ).css("background-color",$(this).val()); But this one does? $("#input").val( _back ) ...

Apply a spread of nested elements onto another spread

I am working with an array containing last names of Persons and need to populate new entries. However, I only have the last names and not the full Person objects. How can I address this issue? type Person = { name: string, lastName: string, age: ...

Can the top header stay fixed to the top of the screen even when scrolling down?

Code snippet: http://jsfiddle.net/R3G2K/1/ In my project, there are multiple divs with content and each div has a header. My goal is to make the last header that goes out of viewport "sticky" or fixed at the top. I have explored various solutions for thi ...