'Merge my initial state with data from API

I don't understand why my state data was not merged with my initial state

In my initial state i have:

data: {role: null, lastUrl: null},

When my call api is over, my state is updated with the data from API but my role and last URL property disapears.

I want to update the data of my state with the data from API and add the two properties of my initial state.

Can you explain to me what I've missed please?

For the more important files in my store i have:

One init.model.ts:

export interface Initialization {
    role: string,
    lastUrl: string,
}

One init.actions.ts:

import { Action } from "@ngrx/store";
import { Initialization } from './init.models';

export enum Types {
    INIT = '[Init] Start',
    INIT_SUCCESS = '[Init] SUCCESS',
    INIT_ERROR = '[Init] ERROR',
}

// Init
export class Init implements Action {
    readonly type = Types.INIT;
    constructor() { }
}

export class InitSuccess implements Action {
    readonly type = Types.INIT_SUCCESS;
    constructor(public data: Initialization) { }
}

export class InitError implements Action {
    readonly type = Types.INIT_ERROR;
    constructor(public error: string) { }
}

export type All
    = Init
    | InitSuccess
    | InitError;

One init.reducers.ts

import { Initialization } from './init.models';
import * as fromActions from './init.actions'

export interface InitState {
    data: Initialization;
    loading: boolean;
    error: string;
}

const initialState = {
    data: {role: null, lastUrl: null},
    loading: null,
    error: null,
}

export function reducer(state: InitState = initialState, action: fromActions.All) {
    switch (action.type) {
        // Init
        case fromActions.Types.INIT: {
            
            return { ...state, loading: true, error: null };
        }

        case fromActions.Types.INIT_SUCCESS: {
            return { ...state, data: action.data, loading: false, error:null };
        }

        case fromActions.Types.INIT_ERROR: {
            return { ...state, loading: false, error: action.error };
        }

        default: {
            return state;
        }
    }
}

One init.effects.ts:

import { map, switchMap, catchError } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Observable, of } from 'rxjs';
import * as fromActions from './init.actions';
import { ConfigService } from '@app/services/config/config.service';



type Action = fromActions.All;

@Injectable()
export class InitEffects {
    constructor(
        private actions: Actions,
        private config: ConfigService,
    ) { }

    init: Observable<Action> = createEffect(() => 
        this.actions.pipe(
            ofType(fromActions.Types.INIT),
            switchMap(() => {
                return this.config.load().pipe(
                    map(
                        init => {
                            return new fromActions.InitSuccess(init || null)
                        }
                    ),
                    catchError(err => of(new fromActions.InitError(err.message)))
                );
            })
        )
    )

}


Solution 1:[1]

spread your current state into a new object that you will then pass back

{ ...initialState, data: action.data, loading: false, error:null };

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ruben Verster