What is the best way to dismiss a MatDialogBox or any div once the API call is successful within NGXS state?

I've recently delved into learning state management with NGXS. While things are going smoothly, I do have a couple of questions regarding specific scenarios:

  1. How can I close a Mat Dialog box (or any div) only if an API call initiated from within it returns success?

  2. Upon user logout, how can I reset states to their default values?

Here's a snippet of my code for the first scenario, including the action and dispatcher:

abc.action.ts

export class AddExamCategory {
    static readonly type = '[ExamCategory] Add';
    constructor(public payload: ExamCategory) {}
}

abc.state.ts

export interface ExamCategoryStateModel {
    examCategoryList: ExamCategory[];
}

@State<ExamCategoryStateModel>({
    name: 'examCategory',
    defaults: {
        examCategoryList: []
    }
})

@Injectable()
export class ExamCategoryState {

    constructor(private _adminService: AdminService) {}

    @Action(AddExamCategory)
    addExamCategory({ getState, patchState }: StateContext<ExamCategoryStateModel>, { payload }: AddExamCategory) {
        return this._adminService.createExamCategory(payload).pipe(tap(response => {
            patchState({ examCategoryList: [] }); // Want to close the modal/div after this part. If API returns ERROR do not close.
        }));
    }
}

abc.component.ts

this.store.dispatch(new AddAdminUser({ ...this.adminRegistrationForm.value, password: this.password.value }))
    .subscribe(response => {
      this.store.dispatch(new GetAdminUsers());
      this.dialogRef.close(true)
    });

The current behavior is closing the dialog regardless of the API response status.

For the second scenario, in the service where I handle the logout() logic, I'm using this.store.reset({}). While this resets the states, it doesn't revert them to their default values. How can I achieve that for multiple states during logout?

Appreciate any guidance on tackling these situations effectively.

Answer №1

To keep track of the requesting state in your application, you can add an additional property to your state (e.g., 'requesting' or 'idle'). You may create extra states as necessary to monitor responses like 'success' and 'error' from the server.

When dispatching GetAdminUsers, update the newly added state to requesting. Upon completion of GetAdminUsersComplete, set the value to idle.

In your ngOnInit, subscribe to a selector that reads the state and executes dialogRef.close(true) within it. Here's an example:

this.store
      .pipe(
        select(selectors.selectRequestState),
        skip(1) //only start tracking after request created
      )
      .subscribe(result => {
        if (result == 'idle')
          this.dialogRef.close()
      });

For further reference, check out this example: https://stackblitz.com/edit/angular-ivy-4ofc3q?file=src/app/app.component.html

Resetting the State

If you need to reset the state within the store, one approach is to implement a reset action that reverts the state to its original form. Alternatively, a simple solution is to refresh the browser page after a user logs out using location.reload();

  • If the store is stored in localstorage, remember to remove it before reloading the page.

Answer №2

To make this task easier, consider using an effect. Once you dispatch your action, you can then trigger another action such as "UserAddedSuccessfully". After that, you can close the modal.

For more information, check out this question.

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

The confusion arises from the ambiguity between the name of the module and the name of

In my current scenario, I am faced with the following issue : module SomeName { class SomeName { } var namespace = SomeName; } The problem is that when referencing SomeName, it is pointing to the class instead of the module. I have a requireme ...

Activating the click event on the Bootstrap-select plugin through coding

Is there a way to programmatically trigger the on-click event for the second option (select TV) in bootstrap-select plugin? I want to replicate the behavior as if the user clicked on the "TV" option themselves. You can view my code here: https://jsfiddle. ...

Is there a way to deactivate a submit button that is delivered through an Ajax response within a div (popup)?

I have a button that triggers an AJAX request when clicked, opening a popup div with the Ajax response displayed inside. The popup is essentially a form with text boxes and a submit button. I've been attempting to add some JavaScript validations, but ...

Vue3/Vuex - Issue with state change not being reflected in component when utilizing object destructuring

While working with Vue 3 and Vuex, I encountered an issue where Vue did not react to a state change when using object destructuring assignment to mutate the state. However, I found that Vue does react when the state is mutated by a mutation that only reass ...

Discovering escape characters while iterating through a string in javascript

I have a situation where I must rearrange a string into an array for a unique user display. Whenever encountering an escape character (such as \n for a new line), it needs to be added as a separate item in the array. For example, if the string is: sa ...

Set the height of the vertical scroll at a fixed 100% floatValue

Check out my creation at http://jsfiddle.net/ZygnV/ html, body { margin: 0; padding: 0; height: 100%; } .main-content-wrapper { height: 100%; overflow-y: hidden; white-space: nowrap; } .main-sidebar { display: inline-block; height: 1 ...

You are limited to using a maximum of two custom tags within a custom div

I came up with this code that is supposed to style the elements differently based on their tag names. However, when I tested it, the styling did not work as expected. For example, 'London' should be displayed as a large and bold h1 text, while th ...

How and where should you define the Angular catch all route for handling page not found errors?

In my project, I have a primary app.routing.module.ts with the following configuration: const routes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'login', component: LoginComponent }, { path: '', re ...

In Typescript, it is not possible to utilize numbers or arrays within URLSearchParams

The method signature for appending to a URLSearchParams object in TypeScript is defined as append(name: string, value: string): void;. While I successfully appended an array and number in the browser, it resulted in an error when running the TypeScript co ...

When props are used, the styles of styled components are overwritten

Here are some styled components that I have: const Box1 = styled.div` // some styles `; const Box2 = styled.div` background-color: ${({ someProp }) => someProp ? "cyan" : "magenta"}; ${Box1} > & { color: ${({ someP ...

Storing items in localStorage in the same order they were added

I am having an issue with sorting localStorage items by the order they were added. Despite my code working to add items to the localStorage array and display them as HTML, I am encountering a problem with the order of the items. When I add a 3rd item to t ...

Troubleshooting issue with jQuery validation functionality not functioning properly with select dropdown

My default validator settings include displaying a red error message when validation fails. However, it works on Input and textareas, but not on select. $.validator.setDefaults({ ignore: "", errorPlacement: function(error, element) { ...

Using Vue 3's emit in place of v-model

I am facing a challenge with integrating a custom dropdown select component. The idea is to use v-model to retrieve data from the parent component, but I am unsure how to pass that through an emit. Can anyone clarify this for me? Here is my parent compone ...

A guide on Implementing PastBack Functionality with AJAX Responses

When I make a GET request for an HTML page, I come across the following element: <a id="ctl00_cphRoblox_ClaimOwnershipButton" href="javascript:__doPostBack('ctl00$cphRoblox$ClaimOwnershipButton','')">Claim Ownership</a> My ...

Whenever a JavaScript Ajax Call is made, it consistently returns readyState=1 and status=0

I've been using AJAX to send a post request, but I'm running into some issues. Every time I check the xmlhttp.readyState, it's always coming back as 1 and the xmlhttp.status is always 0. Also, the xmlhttp.responseText is consistently empty. ...

What is the best way to distinguish shared services from other services in Angular 6 and above?

There was a time when I frequently heard the term "shared services" in relation to sharing data between unrelated components in Angular. However, I started questioning whether every service is actually classified as a shared service or not. If it is cons ...

Display or conceal a button in Angular 6 based on certain conditions

In my current project, I am facing a challenge where I need to disable a button while a task is running and then activate it once the task is complete. Specifically, I want a syncing icon to spin when the task status is 'In_progress' and then hid ...

Querying a Mongoose nested schema

I've created the following schema: const mongoose = require('mongoose'); const Schema = mongoose.Schema; const ProjectSchema = require('./project.js') const ClientManagerSchema = new Schema({ name : { type : String, required ...

What is the best way to adjust the z-index (greater than 1000) of ngx-material-timepicker within a Material Dialog (MatDialog)?

When the ngx-timepicker-field is inside a MatDialog, it appears behind the modal popup of the dialog. constructor(public dialog: MatDialog) { } const dialogRef = this.dialog.open(PopupComponent, { data: { ... }, position: { to ...

Encountering an error with the Angular 2 SimpleChanges Object during the initial npm start process

Within my Angular 2 application, there exists a component that holds an array of objects and passes the selected object to its immediate child component for displaying more detailed data. Utilizing the "SimpleChanges" functionality in the child component a ...