How to pass an argument to functions mapped using ...mapActions(...)? - javascript

Considering the following passage
export default {
methods: {
...mapActions(["updateData", "resetData"]);
}
}
I'd like to pass in a parameter into the called functions. Not certain how to do so properly while still retaining the ...mapAction() call, I had to rewrite to the following.
export default {
methods: {
// ...mapActions(["updateData", "resetData"])
updateData: function() { this.$store.dispatch("updateData", "names") },
resetData: function() { this.$store.dispatch("resetData"); }
}
}
Is this the only way?

You can just pass the parameter to the method, where you are calling it. you can only send one parameter, which will be available in the actions. You don't have to do anything special when using mapActions
For example you can call it like:
<button #click=updateData({data1: 1, data2: 2})>
and in the vuex store:
const actions = {
updateData: (state, data) => {
//You will get passed parameter as data here
},
and you can still use mapActions:
export default {
methods: {
...mapActions(["updateData", "resetData"]);
}
}
see working fiddle here: you can see passed parameter in the alert :)
Here is the implementation of mapActions from vuex repo
export function mapActions (actions) {
const res = {}
normalizeMap(actions).forEach(({ key, val }) => {
res[key] = function mappedAction (...args) {
return this.$store.dispatch.apply(this.$store, [val].concat(args))
}
})
return res
}
You can see it takes the args passed and puts them as a second argument of dispatch function.

Related

No reactivity between service and component

I take out the logic in the service separately from the component.
There is a property in the logic, on which the display of the element in the component depends
The property is declared like this:
function serviceAbonent () {
...
const switchAdd = ref(false)
...
return { switchAdd }
}
In the component, I get this property like this:
const { stitchAdd }= serviceAbonent()
In this method, I call the service method, which changes the value of the property
function newItemAdd () {
serviceAbonent().add(newItemBlack, 'Black', 'CreateDate')
}
service method:
async function add (newItem :any, list: string, defaultSort: string) {
switchAdd.value = false ...
The problem is that when the value changes, the value only changes in the service, but does not change in the component. Why is that ?

Method in vuex action return undefined

I have the following method in my Vuex action:
const actions = {
async fetchByQuery({ commit, title }) {
console.log(title);
//other codes
},
};
And method to reach to vuex action:
methods: {
...mapActions(["fetchByQuery"]),
getData(title) {
console.log("teacher");
this.fetchByQuery(title);
}
}
But the console.log() from action is giving undefined output in the console.
What am I missing here ??
You got the parameters inside your action wrong.
({ commit, title }) has to be ({ commit }, title)
Otherwise you would have to call it with an object with a property title.
Vuex actions expect two parameters, the context object { commit } and the payload (title, in your case)
Change your action declaration to this:
const actions = {
async fetchByQuery({ commit }, title) {
console.log(title);
//other codes
},
};

I can't access modified window.location object jest in another module

I want to mock window.location.search.
config.test.js
import config from './config'
import { MULTIPLE_VIDEOS } from './Constants/flagKeys'
describe('', () => {
const flag = { [MULTIPLE_VIDEOS]: true }
global.window = Object.create(window)
Object.defineProperty(window, 'location', {
value: {}
})
afterAll(() => {
global.window = null
})
it('Mark query string flag as true', () => {
global.window.location.search = `?${MULTIPLE_VIDEOS}=true`
expect(config.flags).toEqual(flag)
})
})
config.js
export default { flags: getFlagsFromQueryString() }
function getFlagsFromQueryString () {
const queryString = qs.parse(window.location.search.slice(1))
const flags = {}
Object.entries(queryString).forEach(([name, value]) => {
flags[name] = value.toLowerCase() === 'true'
})
return flags
}
Though I set search value in location object before calling config.flags, I can't access it inside the function, It always returns empty string.
I want window.location.search.slice(1) to return ?multipleVideos=true inside getFlagsFromQueryString function instead of empty string, since I changed the value in the test file.
One thing I noticed, when I export the function and call in the test file it works.
For this type of complex uses. I would recommend you to create a Window service/util class and expose methods from there. easy to test and mock.
Sample:
// Window.js
class Window {
constructor(configs) {}
navigate(href) {
window.location.href = href;
}
}
export default new Window({});
Now you can easily mock Window.js. It is similar to DI pattern.

Passing a parameter to a function inside a named export object literal

When using a named export to return an object literal composed of functions, is it possible to pass a parameter to one of those functions?
For example, let's say the function below returns conditional results depending on if user's an admin:
// gridConfig.js
function getColumnDefs(isAdmin = false) {
// conditionally return columns
return {
orders: [ ... ],
...
}
}
export const config = {
columnDefs: getColumnDefs(),
rowDefs: getRowDefs(),
...
};
// main.js
import { config } from './gridConfig';
function doStuff() {
const { columnDefs, rowDefs } = config;
grid.columnDefs = columnDefs['orders'];
...
}
If I add the parameter to the function call inside the export, it says the param isn't defined. Adding a parameter to the export alias gives syntax errors. Even if it allowed this, I'm not clear where I'd pass my param inside main.js.
Is there some way of passing a parameter when structuring an export in this manner?
Maybe keeping it simple can be useful :)
export const config = (isAdmin) => ({
columnDefs: getColumnDefs(isAdmin),
rowDefs: getRowDefs(),
...
});
// Import
import { config } from '[...]'; // Placeholder path of import
const myConfigFalse = config(false);
const myConfigTrue = config(true);
export const config = admin => ({
columnDefs: getColumnDefs(admin),
rowDefs: getRowDefs(),
});
// main.js
import { config } from './gridConfig';
function doStuff() {
const { columnDefs, rowDefs } = config(admin);//get the admin variable set before this line
grid.columnDefs = columnDefs['orders'];
...
}

How to use Vue plugin in Store?

Is there a proper / documented way of using a plugin inside vuex module or plain js module?
I am using event bus to acheive it, not sure if it is the correct / best way. Please help.
Plugin1.plugin.js:
const Plugin1 = {
install(Vue, options) {
Vue.mixin({
methods: {
plugin1method(key, placeholderValues = []) {
return key;
},
},
});
},
};
export default Plugin1;
In App.vue:
Vue.use(Plugin1, { messages: this.plugin1data });
In store / plain-js module:
const vue = new Vue();
const plugin1method = vue.plugin1method;
you can access your Vue instance using this._vm;
and the Vue global using import Vue from 'vue'; and then Vue;
I'm guessing you defined an instance method, so it would be the former (this._vm.plugin1method())
update
I can't tell you which way you should use it because it I can't see how your function is defined in your plugin.
However, here is an example that should illustrate the difference between instance and global
const myPlugin = {
install: function(Vue, options) {
// 1. add global method or property
Vue.myGlobalMethod = function() {
// something logic ...
console.log("run myGlobalMethod");
};
Vue.mixin({
methods: {
plugin1method(key, placeholderValues = []) {
console.log("run mixin method");
return key;
}
}
});
// 4. add an instance method
Vue.prototype.$myMethod = function(methodOptions) {
console.log("run MyMethod");
// something logic ...
};
}
};
Vue.use(Vuex);
Vue.use(myPlugin);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
this._vm.$myMethod();
Vue.myGlobalMethod();
this._vm.$options.methods.plugin1method(); // <-- plugin mixin custom method
state.count++;
}
}
});
when you commit the increment ie: this.$store.commit('increment') both methods will execute

Categories