FormData as payload to vuex action - vuex

I need help. There is anyway to send FormData as payload for Vuex Action?
methods: {
...mapActions({
sendMessage: 'modules/modal/send_message'
}),
Send() {
this.End = !this.End
this.AutoClose()
this.msg.append('name', this.Name)
this.msg.append('phone', this.Phone)
console.log(this.msg)
this.sendMessage(this.msg)
},
And in Actions
const actions = {
send_message(payload) {
Axios({
method: 'post',
url: 'http://localhost:8080/api/content/create?type=Emails',
data: payload,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
}
But server responding:
[Create] error: no multipart boundary param in Content-Type

Add an empty {} as first argument to your action and it should work.
const actions = {
send_message({}, payload) {
...
Action handlers receive a context object which exposes the same set of methods/properties on the store instance, so you can call context.commit to commit a mutation, or access the state and getters via context.state and context.getters.
Reference

Related

why i can not update data using vuex module?

here is my component
methods:{
...mapActions(['udpateUsers']),
Update(userID){
let formData = new FormData();
formData.append('new_name',this.editUser.new_name);
formData.append('_method', 'PUT');
let config = {
headers:{
'Content-Type':'multipart/form-data',
}
}
this.udpateUsers(userID,formData,config);
}
when i click update button the formData can not be sent to the server but when i console it the FormData is has all the fields
here is my modules
mutations:{
ADD_USER: (state,response)=>{
state.Users = response;
},
UPDATE_USERS: (state,response)=>{
state.Users = response;
}
},
actions:{
udpateUsers: ({commit},userID,formData,config)=>{
http.put("/admin/update/"+userID,formData,config)
.then((response)=>{
commit("UPDATE_USERS",formData);
console.log(response);
})
.catch((error)=>{
console.log(error.response);
})
}
}
export default auth
i think the error will be my commit mutation
You can't pass multiple parameters as payload to Vuex Actions. You'll need to wrap it all up in an object and pass it as a single param.
udpateUsers: ({commit}, { userID, formData, config }) => {
// send to backend
}
this.udpateUsers({ userID, formData, config });
EDIT: From comments, it seems that you're using PUT method instead of POST in your VueX implementation, which is why your backend wasnt getting the data.

Vuex store cannot be used inside axios handler

I have method being successfully called by a button in my Vue component:
methods: {
goTestMe() {
console.log(this.$store.state.lang+' 1')
let url = 'some api url'
let headers = { headers: { 'Content-Type': 'application/json' } }
this.$axios
.get(url, headers)
.then(function(response) {
console.log('here')
console.log(this.$store.state.lang+' 2')
})
The problem is that the output of this is:
en-us 1
here
When it should be:
en-us 1
here
en-us 2
Clearly, the reference to this.$store.state is failing in the then() handler of the axios call.
Why is this? How can I send data received by my axios request to the Vuex store?
when you add the callback in the normal function you can't access the global object so you need to change it to an arrow function
methods: {
goTestMe() {
console.log(this.$store.state.lang+' 1')
let url = 'some api url'
let headers = { headers: { 'Content-Type': 'application/json' } }
this.$axios
.get(url, headers)
.then((response) => { // change it to arrow function
console.log('here')
console.log(this.$store.state.lang+' 2')
})
}

Redux Middleware, POST Request

I wrote functions for sending requests using redux api middleware. What does the POST function look like instead of GET?
RSAA getOrdersRequest(){
return RSAA(
method: 'GET',
endpoint: 'http://10.0.2.2:80/order',
types: [
LIST_ORDERS_REQUEST,
LIST_ORDERS_SUCCESS,
LIST_ORDERS_FAILURE,
],
headers: {
'Content-Type':'application/json',
},
);
}
ThunkAction<AppState> getOrders() => (Store<AppState> store) => store.dispatch(getOrdersRequest());
my function is written in dart, but the language of the example is not important,
thanks for any help
For making async calls, you should use middlewares like redux-thunk. I'll be using JavaScript here.
All you need to know about thunk is that redux-thunk allows your action creator(like postOrder) to return a function which then dispatches respective actions(object with a type and payload/data property) to the store. You can dispatch as many actions as you like.
POST is just a HTTP verb that I'm using to post an order, as you could see down here. Firstly, POST_ORDERS_REQUEST is the beginning of your request, in which, you could show loading... state or a spinner in your application. So, this action fires off, orderReducer checks what type of action has arrived, and in turn, acts accordinly and stores the data in the redux-store. I'm sure you know basic redux, so it might not be a problem for you to understand all this. The other two actions work the same way.
export const postOrder = () => {
return async (dispatch) => {
dispatch({
type: POST_ORDER_REQUEST
})
try {
const res = await axios.post("http://10.0.2.2:80/order",
{
headers: {
"Content-Type": "application/json",
}
})
dispatch({
type: POST_ORDER_SUCCESS,
data: { order: res.data.order }
})
} catch (err) {
dispatch({
type: POST_ORDER_FAILURE,
data: { error: `Order failed with an ${err}` }
})
}
}
}
You could accordingly create your orderReducer, for example:
const initialState = {
isLoading: false,
myOrder: null,
error: null
}
export const orderReducer = (state = initialState, action) => {
switch (action.type) {
case POST_ORDER_REQUEST:
return {
...state,
isLoading: true,
error: null
}
case POST_ORDER_SUCCESS:
return {
...state,
isLoading: false,
myOrder: action.data.order,
error: null
}
case POST_ORDER_FAILURE:
return {
...state,
isLoading: false,
error: action.error
}
default:
return state
}
}
You can read these good articles on Redux that you might like:
https://daveceddia.com/what-is-a-thunk/
https://daveceddia.com/where-fetch-data-redux/
since accepted response had nothing to do with redux api middleware which is made in order to reduce "boilerplatish" and repetitive thunk code, you can use createAction from redux-api-middleware like:
import { createAction } from "redux-api-middleware";
export const getOrders = () =>
createAction({
endpoint: 'http://10.0.2.2:80/orders',
method: "GET",
types: ['GET_ORDERS_PENDING', 'GET_ORDERS_SUCCESS', 'GET_ORDERS_FALED'],
});
export const getOrderById = (id) =>
createAction({
endpoint: `http://10.0.2.2:80/orders/${id}`,
method: "GET",
types: ['GET_ORDER_BY_ID_PENDING', 'GET_ORDER_BY_ID_SUCCESS', 'GET_ORDER_BY_ID_FALED'],
});
export const submitOrder = (name, price) =>
createAction({
endpoint: 'http://10.0.2.2:80/orders',
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: name,
price: price,
}),
types: ['SUBMIT_ORDER_PENDING', 'SUBMIT_ORDER_SUCCSESS', 'SUBMIT_ORDER_FAILED'],
});
in cases where you could use more handling than simple api service calling you can always combine it with thunk like this

Put API KEY in axios

I just started learn React but I have problem when I trying to make a request to the CoinMarketCap API with axios and tried several ways to set my API key. I have also also tried on Postman but message appears API key missing.
export const apiBaseURL = 'https://pro.coinmarketcap.com';
Tried like this
dispatch({ type: FETCHING_COIN_DATA })
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map`,
{ headers =
{ 'X-CMC_PRO_API_KEY': 'apicode', }
})
this
dispatch({ type: FETCHING_COIN_DATA })
let config = { 'X-CMC_PRO_API_KEY': 'apicode' };
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map`, { headers: config })
and this
dispatch({ type: FETCHING_COIN_DATA })
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map?X-CMC_PRO_API_KEY=apicode`)
Thank you
The short answer to adding an X-Api-Key to an http request with axios can be summed up with the following example:
const url =
"https://someweirdawssubdomain.execute-api.us-east-9.amazonaws.com/prod/custom-endpoint";
const config = {
headers: {
"Content-Type": "application/json",
},
};
// Add Your Key Here!!!
axios.defaults.headers.common = {
"X-API-Key": "******this_is_a_secret_api_key**********",
};
const smsD = await axios({
method: "post",
url: url,
data: {
message: "Some message to a lonely_server",
},
config,
});
Adding the key to the default headers was the only way I could get this to work.
Use CMC_PRO_API_KEY as a query parameter, instead of X-CMC_PRO_API_KEY:
dispatch({ type: FETCHING_COIN_DATA })
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map?CMC_PRO_API_KEY=apicode`)
I realize this has been solved; for the sake of alternatives here is how I did it. I created a instance of axios in /includes/axios:
import axios from "axios";
const instance = axios.create({
baseURL: "https://example.com/api",
headers: {
"Content-Type": "application/json",
"x-api-key": "****API_KEY_HERE****",
},
});
export default instance;
Now axios can be imported anywhere in the project with the give configuration. Ideally you want to add your secret to the ENV variable for security reasons.

cant import vuex store to request file

i am trying to call a mutation when a request is sent and response has came.
this is my request file:
import axios from 'axios'
import router from '#/router'
import _ from 'lodash'
const instance = axios.create({
baseURL: process.env.BASE_URL,
timeout: 31000,
headers: {
Accept: 'application/json'
},
});
const token = localStorage.getItem('access_token');
if(!_.isNil(token)) {
instance.defaults.headers.Authorization = 'Bearer ' + token;
}
instance.interceptors.response.use(function (response) {
return response
}, function (error) {
if (error.response.status === 401) {
router.push('/introduction')
}
});
export default instance
and this is my main store
const vuexLocal = new VuexPersistence({
storage: window.localStorage
});
Vue.use(Vuex);
axios.defaults.baseURL = 'http://api.balatar.inpin.co/';
export const store = new Vuex.Store({
plugins: [vuexLocal.plugin],
modules: {
user,jobPost, company, application, cvFolder, event
},
state: {
loader:''
},
getters: {
},
mutations: {
LOADER:function (state, payload) {
state.loader=payload;
console.log('MUTATION')
}
},
actions: {
},
});
when i try to import store like below
impotr {store} from '#/store/store'
and then access the LOADER mutation like this:
store.commit('LOADER')
it returns error that cannot read property commit of undefined. how should i do this?
You should write an action, then send your request by your action and as soon as response arrives you will be able to commit a mutation
for example in the following action:
{
/**
* Login action.
*
* #param commit
* #param payload
*/
login: async function ({ commit }, payload) {
commit('LOGGING_IN')
try {
const result = await fetchApi({
url: 'http://api.example.com/login',
method: 'POST',
body: payload
})
commit('LOGIN_SUCCESS', result)
} catch (error) {
commit('LOGIN_FAILURE', error)
}
}
}
as you can see above, as soon as you call login, it calls LOGGING_IN mutation and sends a request to some address, then it waits for a response.
if it gets success response the LOGIN_SUCCESS mutation with a payload of result commits otherwise it commits LOGIN_FAILURE with a payload of cached error.
note: you should provide your own fetchApi method which is a promise.