I'm working with api for movies, and to create a request to the server, I need to pass it to the header object
{
'X-API-KEY': 'there is apikey',
'Content-Type': 'application/json',
}
I make requests using RTK Query
export const filmsApi = createApi({
reducerPath: 'awaitsFilms',
baseQuery: fetchBaseQuery({
baseUrl: url,
}),
endpoints: (build) => ({
getAwaitsFilms: build.query({
query: () => `top?type=TOP_AWAIT_FILMS`,
}),
}),
})
how do I pass this header object to fetchBaseQuery?
Documentation
import type { RootState } from './store'
const baseQuery = fetchBaseQuery({
baseUrl: '/',
prepareHeaders: (headers, { getState }) => {
const token = (getState() as RootState).auth.token
// If we have a token set in state, let's assume that we should be passing it.
if (token) {
headers.set('authorization', `Bearer ${token}`)
}
return headers
},
})
Related
guys, I'm new in RN. I have a default login endpoint smth like this
export const authApi = api.injectEndpoints({
endpoints: build => ({
login: build.mutation({
query: credentials => ({
url: apiEndpoint.login,
method: 'POST',
body: credentials,
}),
}),
}),
});
export const {useLoginMutation} = authApi;
and i want to get auth token from store after login to prepare headers, but i don't know how to
export const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: apiConfig.apiBaseUrl,
prepareHeaders: (headers, {getState}) => {
const token = getState().api;
if (token) {
headers.set('Authorization', token);
}
headers.set('Accept', 'application/json');
return headers;
},
}),
endpoints: () => ({}),
reducerPath: 'api',
});
What is the correct way to make this? And another question if I want to make it persistent what can I use? I read about AsyncStorage but it's not a secure way
Can somebody tell me why I still get the cached data after I invalidate the getUser query?
api.ts:
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: REACT_APP_API_URL,
prepareHeaders: (headers, { getState }) => {
headers.set('Accept', 'application/json');
const token = (getState() as RootState).auth.token;
if (token) {
headers.set('Authorization', token);
}
return headers;
},
}),
tagTypes: [
'UserGet',
'UserPost',
],
endpoints: () => ({}),
});
userGetApi.ts:
const userGetApi = api.injectEndpoints({
endpoints: (builder) => ({
getUserData: builder.query<UserData, void>({
query: () => '/users/me',
providesTags: ['UserGet'],
}),
}),
overrideExisting: true,
});
export const { useGetUserDataQuery } = userGetApi;
userPostApi.ts:
const userPostApi = api.injectEndpoints({
endpoints: (builder) => ({
saveUser: builder.mutation<void, OnboardingEntry>({
query: (userEntries) => {
const formData = Object.keys(userEntries).reduce((formData, key) => {
formData.append(key, userEntries[key].toString());
return formData;
}, new FormData());
return {
url: '/users/update',
method: 'POST',
body: formData,
};
},
invalidatesTags: ['UserGet'],
}),
}),
overrideExisting: true,
});
export const { useSaveUserMutation } = userPostApi;
The 2 hooks I call:
const { data: { data } = {}, isLoading, isError, isSuccess } = useGetUserDataQuery();
const [saveUser, { isLoading: postIsLoading, isSuccess: postIsSuccess }] = useSaveUserMutation();
After calling saveUser(...), I get redirected to another page. When I revisit the page, I expect to see the updated user data from useGetUserDataQuery(), but I see the previous data. Even when I close and reopen the app, I still get the old data!
So what am I doing wrong here? I'm using 'ProvidesTags' & 'InvalidatesTags' as stated in the docs.
So after days of pure frustration I found the solution: Api headers.
baseQuery: fetchBaseQuery({
baseUrl: REACT_APP_API_URL,
prepareHeaders: (headers, { getState }) => {
headers.set('Accept', 'application/json');
headers.set('Cache-Control', 'no-cache');
headers.set('Pragma', 'no-cache');
headers.set('Expires', '0');
const token = (getState() as RootState).auth.token;
if (token) {
headers.set('Authorization', token);
}
return headers;
},
}),
Hopefully this answer will help others as well
$Happy New Year! So, I'm setting up a redirect after an authentication token retrieval and I keep getting "TypeError: Cannot read properties of undefined (reading '$router')" in the console and the user is not redirected to the desired page ("/dashboard"). I'm outsourcing the authentication to a dataRequests.user.js file that then goes to a vue component. Thanks in advance. Here is the code:
import common from "./dataRequests.commons";
import { login, inputLogin, inputPassword } from '/src/pages/Index.vue'
let userRequest = {}
userRequest.authenticate = (inputLogin, inputPassword) => {
return new Promise(() => {
let axios = require("axios");
let config = {
method: 'post',
baseURL: common.baseURL + '/auth/login',
headers: {
'Content-Type': 'application/json',
},
data : {
login: inputLogin,
password: inputPassword,
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.then(() => this.$router.push(this.$router.redirect || '/dashboard'))
.catch(function (error) {
console.log(error);
//console.log('input login', this.inputLogin)
//console.log('input password', this.inputPassword)
});
console.log('input login', inputLogin)
console.log('input password', inputPassword)
});
}
export default userRequest;
Something like this:
import common from "./dataRequests.commons";
import { login, inputLogin, inputPassword } from '/src/pages/Index.vue'
import axios from 'axios'
import router from 'router'
let config = {
method: 'post',
baseURL: common.baseURL + '/auth/login',
headers: {
'Content-Type': 'application/json',
}
userRequest.authenticate = (inputLogin, inputPassword) => {
const apiClient = axios.create(config)
return new Promise(() => {
apiClient.post(data : {
login: inputLogin,
password: inputPassword,
})
.then(() => router.push...etc
i'm using axios with vuex, i need to send data with json form to execute post request and add new row with axios, i'm using vuex, when action is trigered it doesn't keep the data and sent it on action, the data json is created on vue componment but don't send it to action to execute axios post :
Action.js:
export const addClassification = ({data}) => {
console.log('data actio:', {data})
axios
.post("/vendor/classification/save", data, {
headers: {
"Content-Type": "application/json",
// withCredentials: true //sent with cookie
Authorization: "Bearer " + Vue.$cookies.get("jwt"),
}
})
.then((res) => {
console.log('res', res)
// commit("ADD_TO_CLASSIFICATION", data);
})
.catch((err) => {
console.log(err);
});
state.js:
export default {
vendorClassificationList: [],
}
page.vue:
<BaseButton
label="Modifier"
classValue="btn-outline-primary"
#click.native="addClassificationData"
/>
data() {
return {
submitStatus: "",
name: this.$route.params.name,
id: this.$route.params.id,
code: this.$route.params.code,
jsonData:[]
};
},
methods: {
...mapActions(["addClassification"]),
addClassificationData() {
this.jsonData = JSON.stringify({
id: null,
name: this.name,
code:this.code,
active:true
})
console.log('json is', this.jsonData)
this.addClassification({
data : this.jsonData
})
},
Actions is Vuex receive the vuex context as the first param, as you can see in the docs.
In other words if you change in Action.js:
addClassification = ( {data}) => {
to
addClassification = (vuexContext, {data}) => {
it should do the trick. You can call the param vuexContext, context, destructure it if needed or call it _ if unused (as in your case), doesn't really matter, as long as it's there.
Your vuex action is wrong. You are missing the context which can use argument restructuring. Also, you probably need to send res.data within the commit instead of res, depending on what are you doing in your mutation.
actions: {
addClassification ({ commit }, payload) {
axios
.post("/vendor/classification/save", payload, {
headers: {
"Content-Type": "application/json",
// withCredentials: true //sent with cookie
Authorization: "Bearer " + Vue.$cookies.get("jwt"),
}
})
.then((res) => {
console.log('res', res)
commit("ADD_TO_CLASSIFICATION", res.data);
})
.catch((err) => {
console.log(err);
})
}
}
In Vue I am building a small Userprofile page. It is build on token-authentication using Axios. When mounting this page the token is undefined.
with login a token is placed in the localStorage.
The Axios Get request is build outside the Vue component
Api.js
import axios from 'axios'
export default () => {
return axios.create({
baseURL: `http://localhost:8081/`
})
}
Get request
import Api from '#/services/Api'
let config = {
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem('token')
}
}
export default {
index () {
return Api().get('user/profile', config)
}
}
Vue
<script>
export default {
data: () => ({
user: {}
}),
mounted () {
this.user = UserProfileService.index
console.log(UserProfileService.config)
}
}
</script>
There are many advices and I tried them all. With tics, with commas etc. Who sees the big picture?
Use a request interceptor to set the Authorization header:
// Api.js
export default () => {
const instance = axios.create({
baseURL: `http://localhost:8081/`
})
instance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
return instance
}
I added the code from digital drifter, and solved the problem (with help) with changing the mounted function in Vue.
mounted () {
console.log('mounted')
UserProfileService.index()
.then((res) => {
this.user = res.data
})
}