Can anyone tell me how best to do it? Store API
import axios from "axios";
import {ErrorApi} from "~/utils/tryCallApi";
import {IBaseResponse, UserProfileEntity} from "~/types";
import {getCookieValue} from "~/utils";
import {type Navigator} from "@solidjs/router";
import {paths} from "~/utils/paths";
export type HttpClientActions = {
user: HttpClientActionsProfile
}
type HttpClientActionsProfile = {
profile: () => Promise<IBaseResponse<UserProfileEntity>>;
}
export default function createHttpClient(navigate: Navigator) {
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
withCredentials: true,
headers: {
Accept: 'application/json',
}
})
api.interceptors.request.use((config) => {
const csrfToken = getCookieValue('csrftoken');
if (csrfToken !== null) {
config.headers['X-CSRFToken'] = csrfToken;
}
return config;
})
api.interceptors.response.use(
async (response) => response,
async (error) => {
if(error?.response?.status === 401){
/// This normal practice ????????????????????
setTimeout(() => {
navigate(paths.logIn);
}, 0);
}
const apiError: ErrorApi = {
message: error?.response?.data?.detail,
data: error?.response?.data,
status: error?.response?.status,
result: false
}
return Promise.reject(apiError);
}
)
const httpClient: HttpClientActions = {
user: {
profile: async () => api.post('/user/profile/'),
}
}
return httpClient;
}
import axios from "axios";
import {ErrorApi} from "~/utils/tryCallApi";
import {IBaseResponse, UserProfileEntity} from "~/types";
import {getCookieValue} from "~/utils";
import {type Navigator} from "@solidjs/router";
import {paths} from "~/utils/paths";
export type HttpClientActions = {
user: HttpClientActionsProfile
}
type HttpClientActionsProfile = {
profile: () => Promise<IBaseResponse<UserProfileEntity>>;
}
export default function createHttpClient(navigate: Navigator) {
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
withCredentials: true,
headers: {
Accept: 'application/json',
}
})
api.interceptors.request.use((config) => {
const csrfToken = getCookieValue('csrftoken');
if (csrfToken !== null) {
config.headers['X-CSRFToken'] = csrfToken;
}
return config;
})
api.interceptors.response.use(
async (response) => response,
async (error) => {
if(error?.response?.status === 401){
/// This normal practice ????????????????????
setTimeout(() => {
navigate(paths.logIn);
}, 0);
}
const apiError: ErrorApi = {
message: error?.response?.data?.detail,
data: error?.response?.data,
status: error?.response?.status,
result: false
}
return Promise.reject(apiError);
}
)
const httpClient: HttpClientActions = {
user: {
profile: async () => api.post('/user/profile/'),
}
}
return httpClient;
}
4 Replies
Main context
import {createContext, JSXElement, Resource, useContext} from 'solid-js';
import {createStore } from 'solid-js/store';
import createUser, {UserActions} from '~/store/createUser';
import createHttpClient from "~/store/createHttpClient";
import {useNavigate} from "@solidjs/router";
import {IBaseResponse, UserProfileEntity} from "~/types";
export interface AppState {
user: Resource<IBaseResponse<UserProfileEntity>>;
appName: string;
}
type AppActions = UserActions; // & AuthActions
type AppStore = [AppState, AppActions];
export type AppContextProps = {
store: AppStore;
}
const StoreContext = createContext<AppContextProps>();
export function StoreContextProvider(props:{ children: JSXElement }) {
const [state, setState] = createStore<AppState>({
get user() {
return user;
},
appName: 'pdf-parser'
});
const navigate = useNavigate();
const httpClient = createHttpClient(navigate);
const { user, userActions } = createUser(state, setState, httpClient);
const actions = { ...userActions };
const store: AppStore = [state, actions];
return (
<StoreContext.Provider value={{ store }}>
{props.children}
</StoreContext.Provider>
);
}
export function useStore() {
const context = useContext(StoreContext)
if (!context) {
throw new Error("useStore: cannot find a StoreContext")
}
return context.store;
}
import {createContext, JSXElement, Resource, useContext} from 'solid-js';
import {createStore } from 'solid-js/store';
import createUser, {UserActions} from '~/store/createUser';
import createHttpClient from "~/store/createHttpClient";
import {useNavigate} from "@solidjs/router";
import {IBaseResponse, UserProfileEntity} from "~/types";
export interface AppState {
user: Resource<IBaseResponse<UserProfileEntity>>;
appName: string;
}
type AppActions = UserActions; // & AuthActions
type AppStore = [AppState, AppActions];
export type AppContextProps = {
store: AppStore;
}
const StoreContext = createContext<AppContextProps>();
export function StoreContextProvider(props:{ children: JSXElement }) {
const [state, setState] = createStore<AppState>({
get user() {
return user;
},
appName: 'pdf-parser'
});
const navigate = useNavigate();
const httpClient = createHttpClient(navigate);
const { user, userActions } = createUser(state, setState, httpClient);
const actions = { ...userActions };
const store: AppStore = [state, actions];
return (
<StoreContext.Provider value={{ store }}>
{props.children}
</StoreContext.Provider>
);
}
export function useStore() {
const context = useContext(StoreContext)
if (!context) {
throw new Error("useStore: cannot find a StoreContext")
}
return context.store;
}
Best do what?
this is normal practice
setTimeout(() => {
navigate(paths.logIn);
}, 0);
Yes it is in some cases
It's when you want to defer the execution till the next event loop run