How to modify the baseURL in axios depending on the current domain - javascript

What I'm trying to do is to create an Axios instance in my nuxt app and modify the baseURl to be the same as the domain but with some prefixes and import this instance from an external js file.
for example, I tried to interceptors the request and modify the domain but in the normal Axios package there is no referer to the current domain in '#nuxt/axios' module there is the referer of the current domain but only if I use the module:
axiosInstance.js:
import axios from 'axios';
// Note I don't want to use baseURL to be static.
const api = axios.craete();
api.interceptors.request.use( (config) => {
const prefixedDomain = prefixDomian(config.headers.common.refere)
config['baseURL'] = prefixedDomain
return config;
}, (error)=> {
return Promise.reject(error);
});
export default api
test.js:
import api from 'axiosService';
const settings = async () => {
const setting = await api.get('/settings');
return settings
}
export default settings
but this code doesn't work because the header is empty inside the config.
The only result that I want is to create an Axios instance with the baseURL prefixed and can import it and use it in an external file.

Related

How do libraries to provide users a bindData function?

I need to copy the behaviour of, for example, the "create" function of Axios:
// fileOne.js
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://some-domain.com/api'
});
Then to use that baseURL in another file, with another function like this:
// fileTwo.js
import axios from 'axios';
axios.get('/user/12345'); // https://some-domain.com/api/user/12345
Getting this as result:
https://some-domain.com/api/user/12345
How does Axios to bind the baseURL data in his library.
I'm looking that library but i don't understand how they do that.
Please see the official documentation Config Defaults section.
You can specify config defaults that will be applied to every request.
Global axios defaults
axios.defaults.baseURL = 'https://some-domain.com/api';
// use it later
axios.get('/user/12345')
Custom instance defaults
const instance = axios.create({
baseURL: 'https://some-domain.com/api'
});
// use it later
instance.get('/user/12345')
Source code explanation of axios v1.2.1
The Axios class has a defaults
property, axios will merge config when dispatch a request. The axios package will call createInstance to create an axios instance of the Axios class with built-in default config.
There is a buildFullPath function to build the full request URL use baseURL and requestedURL(Absolute or relative URL to combine, in your case, it's /user/12345)

Nuxt.Js axios not using baseURL despite it being set correctly

I want to call an API in asyncData()
async asyncData({ $axios, params, store }) {
let itemUUID = params.item;
let item = await $axios.get("/item/" + itemUUID);
return {item};
}
Problem: Axios is still making the request on http://localhost:3000
if I do a console.log($axios.defaults.baseURL) the correct baseURL of my API is printed.
This also works if I use my store action & make the call by using this.$axios
I am using #nuxtjs/axios 5.13.1 with Nuxt 2.15.6 in SSR mode and configured it with the correct baseURL in the nuxt.config.js
Interestingly, if I edit my page content and a hot module reload is triggered, the correct URL is used. Maybe the question should be if Axios is triggered in the right time, on the server?
Edit: I checked the request that was made on HMR and this was triggered in the client.js.
If I call my store inside the created() hook the request gets executed successfully.
My nuxt.config.js:
publicRuntimeConfig: {
axios: {
baseURL: process.env.EXPRESS_SERVER_URL
}
},
privateRuntimeConfig: {
axios: {
baseURL: process.env.EXPRESS_SERVER_URL,
}
},
I'm not sure what is the NODE_TLS_REJECT_UNAUTHORIZED=0 thing doing but your frontend configuration (Nuxt) is working well so far.
Sorry if I cannot help on the Express part.
Maybe try to setup HTTPS locally on Nuxt: How to run NUXT (npm run dev) with HTTPS in localhost?
TLDR; This was not related at all - I forgot to set the auth token for my backend. At the time of axios init it's not present. $axios object doesn't have auth - backend fails.
On page load the nuxt function nuxtServerInit() is used to get the auth token out of the acces_token cookie.
I am using a plugin to initialize Axios - with the token from the store.
But of couse the token is not present at the time axios is initialized as nuxtServerInit is called after plugin init.
In my axios.js plugin I changed:
export default function({ app, error: nuxtError, store }) {
const token = const token = store.state.user.token;
app.$axios.setToken(token, "Bearer");
}
to;
export default function({ app, error: nuxtError, store }) {
const token = app.$cookies.get("access_token");
app.$axios.setToken(token, "Bearer");
}
Now the token is present & used for every request happening server-side.

Axios custom instance not working properly with next JS

So firstly i create custom axios instance with baseurl and export it like this:
import axios from 'axios';
const instance = axios.create({
baseURL: process.env.BACKEND_URL,
});
instance.defaults.headers.common['Authorization'] = 'AUTH TOKEN';
instance.defaults.headers.post['Content-Type'] = 'application/json';
export default instance;
The problem is in my saga or in any component in general (ONLY client side) when importing this custom axios instance. I use next-redux-wrapper, and when i prefetch data (using getStaticProps) for my component everything works fine and the axios.defaults.baseURL property works just fine.
However the problem is on client-side, whenever i import the same axios instance in any component or in saga but i call it from lets say componentDidMount, the same axios.default.baseURL is undefined, so if i want to make get request i have to type in the full backend + queries URL. What could the problem be? EXAMPLE:
export function* fetchTPsSaga() {
try {
console.log(axios.defaults.baseURL);
const url = `/training-programs`;
const res = yield axios.get(url);
const tPs = res.data.data;
yield put(fetchTrainingProgramsSuccess(tPs));
} catch (err) {
yield put(fetchTrainingProgramsFail(err));
}
}
// The first time it renders (on server side), it's the valid baseURL property, however if i call the same saga from client-side (when component is rendered) it's UNDEFINED, so i have to type the full url
process.env only work on server-side. You can use publicRuntimeConfig to access environment variables both on client and server-side.
next.config.js
module.exports = {
publicRuntimeConfig: {
// Will be available on both server and client
backendUrl: process.env.BACKEND_URL,
},
}
axios instance file
import axios from 'axios';
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
const instance = axios.create({
baseURL: publicRuntimeConfig.backendUrl,
});
By the way, if you are using Next.js versions 9.4 and up, the Environment Variables provide another way.
Loading Environment Variables Rules
In order to expose a variable to the browser you have to prefix the variable with
NEXT_PUBLIC_
. For example:
NEXT_PUBLIC_BACKEND_URL='http://localhost:3000'
Then you can access this env variable in Axios as its client-side rendering
import axios from 'axios';
const instance = axios.create({
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
});
*Note: You have to use process.env.NEXT_PUBLIC_BACKEND_URL instead of process.env.BACKEND_URL

Nuxt.js axios request cached inside asyncData after deployment

Why axios requests will be cached after deployment? I've deploy my nuxt.js project with command nuxt generate and when share my project to shared hosting and refresh the page then post updates or new comments to post not showed. I make axios request inside asyncData method.
Code:
import axios from 'axios'
export default {
async asyncData({ req, params }) {
let [post, comments] = await Promise.all([
axios.get(`/post/${id}`),
axios.get(`/post/${id}/comments`),
])
return {
post: post.data,
comments: comments.data
}
}
}
How I can make axios request which not will be cached generaly in Nuxt.js?

How to configure using Styleguidist with Apollo/GraphQL

I'm trying to use GraphQL to populate fake data for Styleguidist. I'm using Express to make my GraphQL server but I'm unsure how to connect Apollo into Styleguidist? The examples use the index.js file and wrap the root component in an tag for Apollo.
I am unsure how Styleguidist works, I don't know where the index.js file is.
There are ways to configure Styleguidist through webpack, but I don't know how to use webpack to use Apollo.
Each example in Styleguidist is rendered as an independent React tree, and the Wrapper component is the root component, so you need to override it as show in the Redux example like this:
// lib/styleguide/Wrapper.js
import React, { Component } from 'react';
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
const client = new ApolloClient({ /* ... */ });
export default class Wrapper extends Component {
render() {
return (
<ApolloProvider client={client}>
{this.props.children}
</ApolloProvider>
);
}
}
// styleguide.config.js
const path = require('path');
module.exports = {
styleguideComponents: {
Wrapper: path.join(__dirname, 'lib/styleguide/Wrapper')
}
};
So you can use Styleguidist in two ways, one by using Create React App then installing an NPM Styleguidist package. Then the other method that I found is starting from an example github registry and replacing the components as you go. I had done the first: where I used Create React App so Webpack was not installed in my main folder but was being used in the NPM module.
With that method I was getting the error:
"Module parse failed: Unexpected token (16:6)
You may need an appropriate loader to handle this file type."
Which means that I needed to configure Webpack. I didn't solve this, but it may just need to have styleguide.config.js file configured to work with Babel. (just a guess)
So, could not (so far), successfully use the Wrapper that solves the problem. So instead I downloaded an example of Styleguidist at https://github.com/styleguidist/example and started fresh. I'm not sure what the difference is, but when I used a wrapper it worked well to add an ApolloProvider wrapper to every component on my page.
To get Apollo 2 to work though you also need to use HttpLink and InMemoryCache. The have a general setup about this at: https://www.apollographql.com/docs/react/basics/setup.html. Under creating a client.
I was using a different port for my GraphQL server because it was using a GraphQL/Express server at port 4000 and Styleguidist by default is at port 6060. So I did two things: passed a uri to the new HttpLink and added a line to the express server to allow cors.
The ref for cors in Express GraphQl and Apollo server:
https://blog.graph.cool/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
So my wrapper file looks like:
import React, { Component } from 'react';
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
const link = new HttpLink({
uri: 'http://localhost:4000/graphql'
});
const client = new ApolloClient({
link,
cache: new InMemoryCache()
});
export default class Wrapper extends Component {
render() {
return (
<ApolloProvider client={client}>
{this.props.children}
</ApolloProvider>
);
}
}
and my server file looks like:
const express = require('express');
const expressGraphQL = require('express-graphql');
const schema = require('./schema/schema');
const cors = require('cors');
const app = express();
app.use(cors());
app.use('/graphql', expressGraphQL({
schema: schema
, graphiql: true
}));
app.listen(4000, () => {
console.log('..listening');
});

Categories