By default, SpringBot redirects a user back to the CRUD list upon successful persistence of an entity. In certain circumstances, this is not desired and as such the redirect can be customised to be dynamic based on the submitted data.
Model

For this article we will be using our Fishnatics entity model as our example. Specifically our ‘Tank’ entity.
The current behaviour redirects the users back to the CRUD list as shown below upon successful persistence.
Task
In this article we will be stepping through the process of adding custom actions upon the successful creation of an entity instance in the CRUD tile.
AdminTankTileCrudComponent::onCreateOrSaveClicked
The first method we will explore is the onCreateOrSaveClicked
found within clientside/src/app/admin/tiles/crud/tank/tank.admin.tile.crud.component.ts
.
This method is triggered when the save button is clicked within the create/update view of the CRUD tile and manages the persistence of the data.
Within this method, there are a couple of important elements.
TargetModel
The target model contains all the data for the model which is being saved/updated.
This is accessible through the use of this.targetModel
. Placing a debugger breakpoint here we can see this.

Persistence
As mentioned before, this method controls the persistance of the updated targetModel
. This is achieved through the use of an NgRx action.
This method controls both the creation and update actions and these are treated differently based on the condition event.isCreate
.
The state is first set with the target model data. We can modify out state before persisting in the protected region here called Add any additional onCreateOrSaveClicked logic before the main body here
.
let stateConfig: PassableStateConfig<TankModel> = {
targetModel: this.targetModel,
queryParams: this.queryParams,
collectionId: this.collectionId
};
Before the event is then triggered, the after action list is set; this list of actions includes a redirect to the CRUD list page.
let afterwardActions: NgRxAction[] = [
new routingAction.NavigateRoutingAction(['admin', 'entities', 'tank'])
];
To override this default action turn on the protected region called Add any additional logic before creating a new model here
and place your new actions in here.
For example, to route back to the home page after save, you would add the following:
// % protected region % [Add any additional logic before creating a new model here] on begin
afterwardActions = [
new routingAction.NavigateRoutingAction(['home'])
];
// % protected region % [Add any additional logic before creating a new model here] end
One issue you will note here is we have access to the pre-persistance state, but not anything that may be returned from the server for this action.
We will look at actions pertaining to data from the server in a moment.
Now, after all actions have been defined, the CreateTankModel
action is dispatched.
this.store.dispatch(new modelAction.CreateTankModel(
stateConfig,
// % protected region % [Add any additional constructor arguments for CreateModel here] off begin
// % protected region % [Add any additional constructor arguments for CreateModel here] end,
afterwardActions
));
Post Save
Some actions may require updated state from the server to execute. The NavigationAction
built into SpringBot is stateless in so much, that it is unaware of the state of the current model.
To achieve state aware routing, we will need to create a new action.
- Open the file called
tank.model.action.ts
found atclientside/src/app/models/tank/tank.model.action.ts
. Find and activate the protected region calledAdd any additional model actions here
. -
Add the following:
// % protected region % [Add any additional model actions here] on begin STATE_AWARE_POST_SAVE_REDIRECT = '[ENTITY] Redirected successfully' // % protected region % [Add any additional model actions here] end
- Find and activate the protected region called
Add any additional actions here
. -
Add the following:
export class StateAwareRoutingAction extends BaseTankAction { readonly type: string = TankModelActionTypes.STATE_AWARE_POST_SAVE_REDIRECT; public constructor( public readonly stateConfig: PassableStateConfig<TankModel>,\ public readonly extras: NavigationExtras = { skipLocationChange: false }, public readonly commands: any[], afterwardActions: Action[] = [] ) { super( afterwardActions ); } }
- Open the the
tank.model.effect.ts
file found atclientside/src/app/models/tank/tank.model.effect.ts
and find the protected region labelledAdd any additional imports here
and activate it. -
Add the following:
// % protected region % [Add any additional imports here] on begin import { Router } from '@angular/router'; import { tap } from 'rxjs/operators'; // % protected region % [Add any additional imports here] end
- We now need to ensure that the target model data can be passed to our new action. Find the protected region called
Add any additional constructor arguments for CreateModelOK here
and activate it. -
Add the following:
// % protected region % [Add any additional constructor arguments for CreateModelOK here] on begin action.afterwardActions.map(afterwardAction => { if (afterwardAction instanceof modelAction.StateAwareRoutingAction) { return new modelAction.StateAwareRoutingAction({ ...action.stateConfig, ...stateConfig }, afterwardAction.commands, afterwardAction.extras) } else { return afterwardAction; } }), // % protected region % [Add any additional constructor arguments for CreateModelOK here] end
This will ensure that the correct data is passed down to your new action after the create action is complete.
**NOTE**: This protected region will be released with SpringBot version 1.2.1.0
- Now to create the effect for your new action. Find the protected region called
Add any additional class methods here
and activate it. -
Add the following:
@Effect({ dispatch: false }) stateAwareRedirect = this.action$.pipe( ofType<modelAction.StateAwareRoutingAction>(modelAction.TankModelActionTypes.STATE_AWARE_POST_SAVE_REDIRECT), tap((action) => { const targetModel = (action as modelAction.StateAwareRoutingAction).stateConfig.targetModel; let commands = (action as modelAction.StateAwareRoutingAction).commands; let extras = (action as modelAction.StateAwareRoutingAction).extras; // Execute any commands const executedCommands = commands.map(command => { if (command instanceof Function) { return command(targetModel); } else { return command; } }); this.router.navigate(executedCommands, extras); }) );
- Our final step is to add this action to our
afterwardsActions
. Opentank.admin.tile.crud.component.ts
found atclientside/src/app/admin/tiles/crud/tank/tank.admin.tile.crud.component.ts
and find the protected region calledAdd any additional logic before creating a new model here
and activate it. -
Add the following:
afterwardActions = [ new modelAction.StateAwareRoutingAction(stateConfig, ['admin', 'entities', 'tank', 'edit', (targetModel: TankModel) => targetModel.id]) ];
This will cause your application to route to edit page for the Tank entity you just created.
i.e.
http://localhost:4200/admin/entities/tank/edit/821a81a3-a780-4e8e-9ca7-8bcd13d824cf