sheaivey / react-axios

Axios Components for React with child function callback
MIT License
180 stars 20 forks source link

manipulate axios Instance #25

Closed soroushm closed 6 years ago

soroushm commented 6 years ago

Hello Dear,

Thank You for making this great tools! I need one more feature about changing axios instance in provider

user scenario: 1- fire login api and will be receive the token 2- now other api needs the token in header

*but there is no way to manipulate existing AxiosProvider instance for the temporary fix i made a axios provider for all private route

router Js

const axiosInstance = axios.create({
    baseURL: 'http://url/,
    timeout: 60000,
    headers: {
        'Authorization': Storage.getItem('token'),
        "Content-Type": 'application/json',
        'x-swapi-key': 'xxxxxxxxxxxxx'
    }
});
<AxiosProvider instance={axiosInstance}>
                        <I18nextProvider i18n={i18n}>
                            <JssProvider jss={jss} generateClassName={generateClassName}>
                                <React.StrictMode>
                                    <BootstrapComp>
                                    <Router history={history}>
                                        <Switch>
                                            <Route exact path="/" component={Landing}/>
                                            <Route path="/login" component={Login}/>
                                            <Route path="/register" component={Register}/>
                                            <Route path="/price" component={Price}/>
                                            <PrivateRoute path="/cart/:planId?" component={Cart}/>
                                            <PrivateRoute path="/branches" component={Branches}/>
                                            <PrivateRoute path="/person/profile" component={PersonProfile}/>
                                            <PrivateRoute path="/receipt/:type" component={ReceiptList}/>
                                            <Route
                                                path="/error"
                                                render={() => <h1>Something went wrong! please try again
                                                    later!</h1>}
                                            />
                                            <Route path="*" render={() => <h1>Not found</h1>}/>
                                        </Switch>
                                    </Router>
                                    </BootstrapComp>
                                </React.StrictMode>
                            </JssProvider>
                        </I18nextProvider>
                    </AxiosProvider>

PrivateRoute

const PrivateRouteComp = ({component: Component, ...rest}) => (
        <Route
            {...rest}
            render={props => {
                const axiosInstance = axios.create({
                    baseURL: 'http://url/',
                    timeout: 60000,
                    headers: {
                        'Authorization': rest.user.me.token,
                        "Content-Type": 'application/json',
                        'x-swapi-key': 'xxxxx'
                    }
                });
                if (!rest.user.me.id)
                    rest.dispatch({type: ActionType.GENERAL.PREV_LOCATION, location: rest.location});

                return rest.user.me.id ? (
                    <AxiosProvider instance={axiosInstance}>
                        <Component {...props} />
                    </AxiosProvider>
                ) : (
                    <Redirect
                        to={{
                            pathname: "/login",
                            state: {from: props.location}
                        }}
                    />
                )
            }
            }
        />
);
const PrivateRoute = connect((state) => (
    {user: state.user}
))(PrivateRouteComp);

So every things look like fine but there is a critical problem for me first its too complex when you want add more in header (in some other url i need send branchId on header for more than 200 Endpoint) ***second my registration is two step in one route --1 call register api and response is a Authorization token key --2 call mobile verification code api (this api need pass Authorization Token in header)

** Problem: -on this case Authorization will not send becouse route is not changing

**solution I'm thinking it will be great pass a function in props for manipulate exsiting instance of axios in header and change will be effect on all api call like:

 axios({
            method: 'post',
            url: '/users/register',
            data: query
        }).then((result => {
            dispatch({type: ActionType.USER.REGISTER, data: result.data.user});
axios.setHeader({'Authorization': result.data.token,})
        }))
soroushm commented 6 years ago

i found solution jusst need user props

this.props.axios.defaults.headers['Authorization'] = token;