This is awesome, thank you. I finally got everything working related to getting the nav menu bar items while still serving from the create-react-app server. I’m using your first recommendation, with LOAD_VIA_AJAX=true.
To be complete here in case anyone else has trouble, window.NAV_ITEMS isn’t available when initialState is first set. However, when console logging window.NAV_ITEMS, this is available, but it’s available too late (after initial state was already loaded). For example, in the following code the nav property is defined using NAV_ITEMS from the window in initialState:
const initialState: State = {
nav: global.NAV_ITEMS as GetNavItemsResponse,
userSession: global.AUTH as AuthenticateResponse,
userAttributes: UserAttributes.fromSession(global.AUTH),
};
and it’s initial state is pass through here in the StateProvider:
export const StateProvider = (props: any) => {
const [state, dispatch] = useReducer( reducer, initialState );
return (<StateContext.Provider value={{ state, dispatch }}>{props.children</StateContext.Provider>);
}
So the state.nav property shows up null even though window.NAV_ITEMS is available in the window. As a test, in the reducer signout case statement, I set the nav item property of state back to the window property for NAV_ITEMS, and it works when signing out (the nav items show up when you click the signout button after first logging in!! Now how to get this on initial load):
const reducer = (state: State, action: Action) => {
switch (action.type) {
case 'signout':
return { nav: global.NAV_ITEMS as GetNavItemsResponse, userSession: null } as State;
}
}
So to fix this, I just had add a member to the Action interface:
interface Action {
type: 'signout' | 'signin' |'setNavBarItems'
data?: AuthenticateResponse | any
}
Then created a function:
export const setNavBarItems = async (dispatch: Dispatch) => {
dispatch({ type: 'setNavBarItems' });
};
Next, I had to add a new case statement in the reducer function:
case 'setNavBarItems':
return { ...state, nav: global.NAV_ITEMS } as State;
And finally, used UseEffects in the StateProvider, to update the nav bar items whenever this window property changes. Like so:
export const StateProvider = (props: any) => {
const [state, dispatch] = useReducer( reducer, initialState );
useEffect(() => {
setNavBarItems( dispatch );
}, [global.NAV_ITEMS]);
return (<StateContext.Provider value={{ state, dispatch }}>{props.children}</StateContext.Provider>);
}
I hope this might help someone else. All of this is in the index.tsx file and running the nav and auth service calls in the same file.
Would you consider adding this back to the docs for people who would still like to use the create-react-app server in the React templates. I just think it’s an awesome developer experience to be able to have auth and nav working with ServiceStack while still having the error overlays working with the create-react-app server. So all works now, thanks again for your help,
–Tim