Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngrx: awaiting of confirm or cancel in a custom dialog

ngrx, angular 7

I need to delete item from list but before I should display a dialog for confirmation. I think best aproach for me is to show dialog via side-effect. I need to show up when delete action was dispatched, catch it in side-effect open a dialog component and return some kind of promise (confirm or cancel). I'm a little bit confused to do this, so I need your help, dear Stackoverflow.

list.component.ts

export class ListComponent {

    list: List;

    constructor(store: Store<fromStore.State>) { }

    deleteItem(itemId: string) {
        this.store.dispatch(new fromStore.DeleteItem);
    }
}

confirm-dialog.component.ts

export class ConfirmDialogComponent {

    constructor() { }

    confirm() {
        // return something to confirm deleting
    }

    cancel() {
        // return something to cancel deleting
    }
}

list.actions.ts

export enum ListActionTypes {
    DeleteItem = '[List] Delete Item',
    DeleteItemSuccess = '[List] Delete Item Success',
    DeleteItemFailure = '[List] Delete Item Failure',

    SetDialogVisibility = '[List] Set Dialog Visibility'
}

export class DeleteItem implements Action {
    readonly type = ListActionTypes.DeleteItem;

    constructor(public payload: string) { } // item id
}

export class DeleteItemSuccess implements Action {
    readonly type = ListActionTypes.DeleteItemSuccess;

    constructor(public payload: string) { }
}

export class DeleteItemFailure implements Action {
    readonly type = ListActionTypes.DeleteItemFailure;
}

export class SetDialogVisibility implements Action {
    readonly type = ListActionTypes.SetDialogVisibility;

    constructor(public payload: boolean) { } // depends on this value I show or hide dialog
}

export type VoyagePageActions = CreateVoyage
    | DeleteItem
    | DeleteItemSuccess
    | DeleteItemFailure
    | SetDialogVisibility;

list.effects.ts

    export class ListEffects {

    constructor(
        private actions$: Actions,
        private store: Store<fromStore.State>
    ) { }

    @Effect() DeleteItem$: Observable<Action> = this.actions$
        .pipe(
            ofType(ListActionTypes.DeleteItem),
            map((action: DeleteItem) => action.payload),
            // show dialog
            // wait for answer
            // send http request to delete item
            // delete item from store
        );
}
like image 532
hofshteyn Avatar asked Jun 04 '19 08:06

hofshteyn


1 Answers

I would say that the dialog doesn't have anything to do with state management. Not everything has to get handled by an effect.

In the case of using angular material I would use the dialog service directly in your ListComponent to display the dialog, and then wait for either the confirm or cancel.

const dialogRef = this.dialog.open(RemoveProjectDialogComponent, {
      data: project
    });

    dialogRef.afterClosed().subscribe(async result => {
      // if result is set, it means the user clicked confirm
      if (result) {
        await this.projectService.remove(this.project.id);
        this.snackBar.open('Project removed');
        this.router.navigate(['/']);
      }
    });
like image 59
Leon Radley Avatar answered Sep 21 '22 11:09

Leon Radley