Is NGXS the most efficient method to deploy start, success, or failure actions from a single action?

In the process of fetching all my posts, I have the code below:

`    @Action(actions.FetchPosts)
    fetchAll(ctx: StateContext<PostStateModel>){
        return this.postService.fetchPosts().pipe(tap((postsResults) => {
            const state = ctx.getState();
                ctx.patchState({
                ...state,
                posts: [                    
                    ...postsResults                    
                ],                
            })
        }),
        mergeMap(() => {
          console.log("Inside of mergeMap")
          return ctx.dispatch(new actions.FetchPostsSuccess())
        }),      
        catchError(err => 
        {
          console.log("Inside of catchError")
          return ctx.dispatch(new actions.FetchPostsFail(err))
        }
      ))
    }`

Although the current implementation works, I am seeking a method to dispatch a start action before calling the post service. How can I ensure that the loading property is set to true during this initial dispatch and only call success once the request is completed successfully?

I am following the ngxs documentation and using mergeMap(), which appears to be effective. However, I would like to know whether the postService returns a single observable or a single observable with multiple inner observables.

Answer №1

To initiate the loading action, you have two options:

@Action(actions.FetchPosts)
fetchAll(ctx: StateContext<PostStateModel>){
    return ctx.dispatch(new ChangeLoadingToInProgress()).pipe(
      mergeMap(() => this.postService.fetchPosts()),
      tap((postsResults) => {
        const state = ctx.getState();
            ctx.patchState({
            ...state,
            posts: [                    
                ...postsResults                    
            ],                
        })
    }),
    mergeMap(() => {
      console.log("Inside of mergeMap")
      return ctx.dispatch(new actions.FetchPostsSuccess())
    }),      
    catchError(err => 
    {
      console.log("Inside of catchError")
      return ctx.dispatch(new actions.FetchPostsFail(err))
    }
  ))
}

Alternatively, you can directly update the state like this:

@Action(actions.FetchPosts)
fetchAll(ctx: StateContext<PostStateModel>){
    ctx.patchState({ loading: true });
    return this.postService.fetchPosts().pipe(tap((postsResults) => {
        const state = ctx.getState();
            ctx.patchState({
            ...state,
            posts: [                    
                ...postsResults                    
            ],                
        })
    }),
    mergeMap(() => {
      console.log("Inside of mergeMap")
      return ctx.dispatch(new actions.FetchPostsSuccess())
    }),      
    catchError(err => 
    {
      console.log("Inside of catchError")
      return ctx.dispatch(new actions.FetchPostsFail(err))
    }
  ))
}

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

Limit the frequency of function calls in Typescript

Update: After some research, I've learned that throttle has the capability to drop excess function invocations, making it unsuitable for my needs. I am still seeking an idiomatic solution to process every item in a queue at an appropriate pace without ...

Using Angular 2 to trigger an event when a native DOM element is loaded

I am working towards my main objective of having a textarea element automatically focused upon creation. I recently came up with an idea to use e.target.focus() on the onload event. It would look something like this: <textarea rows="8" col="60" (load)= ...

An exception is thrown by TypeScript's readline.createInterface function

My current project involves creating an electron app. I am facing an issue in the main.ts file where I have constructed a seemingly simple class with a constructor that is not running as expected. The problem arises when the call to readline.createInterfac ...

Retrieve class attributes within callback function

I have integrated the plugin from https://github.com/blinkmobile/cordova-plugin-sketch into my Ionic 3 project. One remaining crucial task is to extract the result from the callback functions so that I can continue working with it. Below is a snippet of ...

Unable to locate element within the HTML code in Angular

Despite using document.getElementByID, I am unable to retrieve the value of the list element in the HTML. The code shows that the element is undefined, even though it has the same id. Here is the snippet of code: fileupload.component.ts: ngOnInit() { ...

Having trouble testing the ngOnInit() function in a jasmine test case

I am a beginner with Jasmine for Angular 5. As I try to create a test case, my coverage report always shows that ngOnInit() is not covered: https://i.sstatic.net/S7z2j.png Below is my spec file. I am passing null to the constructor of my component, but i ...

Tips for accessing data from a local JSON file in your React JS + Typescript application

I'm currently attempting to read a local JSON file within a ReactJS + Typescript office add-in app. To achieve this, I created a typings.d.ts file in the src directory with the following content. declare module "*.json" { const value: any; ex ...

Embedding an image by inserting the URL

I have been attempting to implement functionality in Typescript where an image preview appears after a user enters a URL, but I have only been successful in achieving this in JavaScript. My goal is to display a preview of the image and enable the user to u ...

What is the best method to integrate my custom Angular Single Page App instead of a webpage using Greasemonkey?

How can I use Greasemonkey to replace the HTML code of a website with my own Angular Single Page App? Motivation: I have come across an old website that is in need of a redesign, but the owner seems uninterested. I want to create an Angular SPA that will ...

Using Angular to convert JSON data to PDF format and send it to the printer

Currently, I am retrieving JSON data from an API and now need to convert this data into a PDF format for printing. I am encountering an issue where the CSS styling for page breaks is not rendering properly within my Angular component. When I test the same ...

Using an Axios interceptor to retrieve responses directly from a Vuex store

I have implemented a login form that utilizes an axios interceptor to manage the response from the API, whether it is successful or not. After receiving the response, it is directed to my vuex store where the user's credentials are stored. However, ...

A Javascript promise that perpetually stays in a pending state

Utilizing the rotateByDegrees function from a library called node-poweredup within a typescript project: motor.rotateByDegrees(20,10).then(function(value) {console.log("test");}, function(value) {console.log("error");}); Expecting to s ...

Is it necessary to establish a new connection each time I make a request to IndexedDB?

Currently, I am working on a basic Angular project and I have the requirement to save some data in IndexedDB. In my service, there is an initialization of private db: IDBDatabase; within the constructor: However, I face an issue where this initialized DB ...

Executing TypeORM commands yields no output

It's been a while since I last tested my Nest project with TypeORM, and now when I try to run any TypeORM command, nothing happens. I attempted to run TypeORM using these two commands: ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js ...

Zod: Establishing minimum and maximum values after converting a string to a numerical value

When dealing with a number or numeric string, I aim to convert it to a number and then validate it using the .min() and .max() methods. However, the results are not matching my expectations. const numberValid = z.number().or(z.string().regex(/^\d+$/). ...

Is it possible for TypeScript to define a decimal type?

When storing price values in the database using MySQL and defining them as decimals, I encountered errors when trying to retrieve the data using tRPC. Types of property 'price' are incompatible. Type 'Decimal | null' is not assigna ...

Angular - Sharing data between components with response value

I am currently in the process of restructuring my project, focusing on establishing communication between unrelated components while also waiting for a return value from a function call. Imagine having component1 with function1() and component2 with funct ...

Typescript's date function offers a variety of useful features

Can anyone help me create a function that formats a date string for sorting in a table? The date is in the format: 08.04.2022 16.54 I need to convert this to a number or date format that can be sorted. I'm new to TypeScript and could use some guida ...

Error encountered: ⨯ Compilation of TypeScript failed

My current project is utilizing Node.js in conjunction with TypeScript An issue has arisen during compilation within my Node.js application: E:\NodeProjects\esshop-mongodb-nodejs\node_modules\ts-node\src\index.ts:859 ret ...

Dynamic typing depending on the individual elements within an array

I am working with some extensions: type ExtensionOptions = { name: string } type BoldOptions = ExtensionOptions & { boldShortcut?: string } type ItalicOptions = ExtensionOptions & { italicShortcut?: string } type LinkOptions = ExtensionOptions &am ...