I would like to know how to handle multiple call to action with different parameters.
How to append the data received for each parameter call in react redux.
Is there any other way to do, or for each id should have seperate action
action.js
export const saleSumm= payload =>
queryApi({
request: CONSTANTS.SALES_SUMMARY,
url: `/api/detail`,
encode: false,
success: CONSTANTS.SUMMARY_SUCCESS,
failure: CONSTANTS.SUMMARY_FAILURE,
...payload
});
//reducer.js
case CONSTANTS.SUMMARY_SUCCESS:
case CONSTANTS.SUMMARY_FAILURE:
return {
...state,
SaleSumm: data, //should append data for each id
apiPending: false,
errormsg: errormsg,
servererror: servererror || ""
};
//index.js
fetchData = (id) =>{
const body = {
id: id,
cn: "MY"
}
return body;
}
renderData=(item)=>{
var mode = ["1010", "1111"];
mode.map(i=>
this.props.dispatch(saleSumm(this.fetchData(i))))
}
render(){
return(
<div>{this.renderData(this.props)}</div>
)
}
Related
I am coding a restaurant reviews app with Vue.js and Django REST Framework.
User can "POST" pictures on their reviews.
As soon as the user click a 'Create review' button, this function is triggered:
addReview () {
let endpoint = `/api/restaurant_review/`;
let method = "POST";
apiService(endpoint, method, { maps: this.$route.params.maps, review_author: 1 })
.then(res => {
let review_id = res.id
console.log(review_id)
return review_id
})
},
So I also get a review_id from my response. I pass it to an other component where the user can upload pictures this way:
<ReviewEditor
:id= "review_id"/>
In my data() I have:
review_id: 0,
So in my ReviewEditor component, I get the id like this:
props: {
id: {
type: Number,
required: true
},
}
And then:
onUpload() {
const fd = new FormData();
let axiosConfig = {
headers: {
'X-CSRFTOKEN': CSRF_TOKEN,
}
};
fd.append('picture_1', this.selectedFile)
fd.append('restaurant_review', this.id)
axios.post('http://127.0.0.1:8000/api/outside_pic/', fd, axiosConfig)
.then(res => {
console.log(res)
})
}
My onUpload() function works well if I pass manually the id, but if I do it dynamically with this.id, I have an error message telling me that 'restaurant_id' = 0, and therefore doesn't exists. I also tried review_id: 0, but with no luck either.
I am trying to pass the value in the state as a parameter to the Function.addAddOnData to which calls the setaddOndatatypes function with " addOnCategory" as a parameter, the parameter is not getting passed on doing console.log it shows blank as the response.
First function call:
const onSubmit = e => {
e.preventDefault();
fileUpload(fileInputRef);
if (!state.loading) {
addAddOnDataToDb(
state.addOnCategory,
state.itemName,
state.itemPrice,
state.itemIconURL
);
}
};
Function:
const addAddOnDataToDb = (
itemName,
itemIconURL,
itemPrice,
addOnCategory
) => {
console.log(addOnCategory);
const addOnType = setAddOnItemType(addOnCategory);
console.log(addOnType);
const addOnBody = JSON.stringify({
itemName,
itemIconURL,
itemPrice,
addOnType
});
console.log(addOnBody);
const config = {
headers: {
'Content-Type': 'application/JSON'
}
};
axios.post('/api/v1/addOn', addOnBody, config);
};
Call to setAddOnItemType
const setAddOnItemType = addOnCategory => {
console.log(addOnCategory);
switch (addOnCategory) {
case 'Add on':
return 'addOn';
case 'Flavours':
return 'flavour';
}
};
You have wrong ordering of arguments at the addAddOnDataToDb call side.
you defined the function like:
const addAddOnDataToDb = (
itemName,
itemIconURL,
itemPrice,
addOnCategory
) => {
....
}
And your call looks like:
addAddOnDataToDb(
state.addOnCategory,
state.itemName,
state.itemPrice,
state.itemIconURL
);
state.addOnCategory should be passed as the last argument to the function call. Also the price and icon url are also in wrong order.
addAddOnDataToDb(
state.itemName,
state.itemIconURL,
state.itemPrice,
state.addOnCategory,
);
I have got a Vue Component which has a list of values, when you select these values this changed the selected array, which in tern is posted to an endpoint.
I have an issue if the user spam clicks these values, as an individual post is created for each change, I want it so that if the user selects another item then the currently pending post is cancelled, so then the new value is posted and updates the endpoint with both the selected items.
However i'm having an issue with aborting the current axios request, I have provided the code below. There are no errors, the request simply doesn't cancel.
export default {
props: {
endpoint: {
default: '',
type: String
},
parameters: {
default: null,
type: Object
}
},
data: () => ({
loaded: false,
selected: [],
save: [],
data: [],
cancel: undefined
}),
methods: {
update() {
const self = this;
let params = this.parameters;
params.data = this.selected;
this.$root.$emit('saving', {
id: this._uid,
saving: true
});
if (self.cancel !== undefined) {
console.log('cancel');
this.cancel();
}
window.axios.post(this.endpoint + '/save', params, {
cancelToken: new window.axios.CancelToken(function executor(c) {
self.cancel = c;
})
}).then(() => {
this.$nextTick(() => {
this.loaded = true;
this.$root.$emit('saving', {
id: this._uid,
saving: false
});
});
}).catch(function (thrown) {
if (window.axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
}
});
}
}
}
I have got a global instance of Axios created on my Vue Application.
I want the same message with different URL, based on a prop. I basically have the below render method, which I call inside my main one.
renderNoBasicMode = () => {
const { securityMode } = this.props;
// Need this, while isFetching securityMode === '',
// Unless, we don't this is rendering on multipel renders.
if (securityMode !== SecurityMode.BASIC && securityMode !== SecurityMode.EMPTY) {
return (
<div className="badge badge-light" data-test="non-basic-mode">
<NoResource
icon="user-o"
title="Non Basic Security Mode"
primaryBtn="New User"
primaryCallback={this.openCreateUserModalPromise}
moreUrl={NonBasicSecurityMode.url}
>
No users available when Lenses is running on {securityMode} security mode.
</NoResource>
</div>
);
}
return null;
};
And I want to display a different url based on the value of the NonBasicSecurityMode, which I have here:
const NonBasicSecurityMode = [
{ securityMode: 'mode1', url: 'https://...' },
{ securityMode: 'mode2', url: 'https://...' },
{ securityMode: 'mode3', url: 'https://...' }
];
The securityMode, is deternment by an API request.
export const securityModeSelector = createSelector(
lensesConfigSelector,
config => (config.&& config['security.mode']) || ''
);
function mapStateToProps(state) {
return {
securityMode: securityModeSelector(state),
};
}
Basically, I tried mapping through them, and a forEach, but I was apparently wrong. Can you help me figure this out? Thanks!!
I'm using vuex to manage the state in my application and doing one way binding with my form.
<script>
import { mapGetters } from 'vuex'
import store from 'vuex-store'
import DataWidget from '../../../../uiComponents/widget'
export default {
data () {
return {
isEdit: false,
msg: {
id: 0,
content: '',
isEnabled: false
}
}
},
components: {
DataWidget
},
computed: mapGetters({
messageId: 'messageId',
messageContent: 'messageContent',
isMessageEnabled: 'isMessageEnabled',
isMessageValid: 'isMessageValid'
}),
methods: {
onSave () {
store.dispatch('saveMessage', this.msg, { root: true })
if (this.isMessageValid) {
this.isEdit = !this.isEdit
}
}
},
created () {
this.msg.id = this.messageId
this.msg.content = this.messageContent
this.msg.isEnabled = this.isMessageEnabled
}
}
</script>
<b-form-textarea id="content" v-model="msg.content" :rows="3" required aria-required="true" maxlength="250"></b-form-textarea>
On load, the values on created() are not binded until I perform an action on the page or refresh the page.
I have tried mounted () hooked same thing.
My Vuex store (Message Module) looks like this:
const state = {
messageId: 0,
messageContent: '',
isMessageEnabled: false,
isMessageValid: true
}
const getters = {
messageId: state => state.messageId,
messageContent: state => state.messageContent,
isMessageEnabled: state => state.isMessageEnabled,
isMessageValid: state => state.isMessageValid
}
const actions = {
getMessage ({commit, rootGetters}) {
api.fetch('api/Preference/Message', rootGetters.token)
.then((data) => {
commit(types.MESSAGE_LOAD, data)
})
}
}
const mutations = {
[types.MESSAGE_LOAD] (state, payload) {
state.messageId = payload ? payload.id : 0
state.messageContent = payload ? payload.content : ''
state.isMessageEnabled = payload ? payload.enabled : false
}
}
export default {
state,
getters,
actions,
mutations
}
and I have a global action (action.js) the gets multiple data:
export const loadSetting = ({ commit, rootGetters }) => {
api.fetchAsync('api/Preference/all', rootGetters.token)
.then((data) => {
commit(types.MESSAGE_LOAD, data.message)
commit(types.HELPDESK_LOAD, data.helpDesk)
commit(types.VOLUME_LOAD, data.volumes)
commit(types.DOWNLOAD_LOAD, data.downloadService)
})
}
My api call:
async fetchAsync (url, token = '') {
let data = await axios.get(HOST + url, {
headers: {
'Authorization': 'bearer ' + token
}
})
return data
}
The problem is your'e calling an async method in Vuex but in the created method, you're treating it like a sync operation and expect to get a value.
You need to use the computed properties you created since they are reactive and will update on every change. In order to make the computed writeable change it to be like this:
computed: {
...mapGetters({
messageId: 'messageId',
isMessageEnabled: 'isMessageEnabled',
isMessageValid: 'isMessageValid'
}),
messageContent(){
get () {
return this.$store.getters.messageContent
},
set (value) {
//this is just an example, you can do other things here
this.$store.commit('updateMessage', value)
}
}
}
And change the html to use messageContent:
<b-form-textarea id="content" v-model="messageContent" :rows="3" required aria-required="true" maxlength="250"></b-form-textarea>
For more info refer to this: https://vuex.vuejs.org/en/forms.html