Destructuring and computed propery name working together, es6 - javascript

I call a function with this code,
gqlActions('customer', 'Add', this.props, values);
or
gqlActions('customer', 'Update', this.props, values);
this funcions is used for add and update actions.
On the function I use computed property, for example in
const tableAction= `${table}${action}`;
[tableAction]: valuesOptimistic,
It's working ok, my problem is in destructuring before, to use that variable after:
update: (store, { data: { [tableAction] }}) => {
data.customers.push([tableAction]);
it's not valid syntax... , before i've used hardcode for 'Add' action :
update: (store, { data: { customerAdd }}) => {
data.customers.push(customerAdd);
},
or
update: (store, { data: { customerUpdate }}) => {
data.customers.push(customerUpdate);
},
becase I send 'update' property to work for a library that sends me the value accord to [tableAction] that I've defined in:
optimisticResponse: {
[tableAction]: valuesOptimistic,
}
I mean parameter in denormalization is variable (update or add). I hope be clear.
my full function:
export const gqlActions = (table, action, props, values) => {
const valuesOptimistic = {
...Object.assign({}, values, __typename: table'})
};
const tableAction= `${table}${action}`;
props.mutate(
{
variables: values,
optimisticResponse: {
[tableAction]: valuesOptimistic,
},
update: (store, { data: { [tableAction] }}) => {
data.customers.push([tableAction]);
},
},
)
}
}

You need to use destructuring using computed property names
update: (store, { data: { [tableAction]:action }}) => {
data.customers.push(action);
}

Related

Unable to pass the required parameters into the URL - Laravel Inertia Vue

I am building a datatable with multi-column sorting functionality. As up to now, the sorting functionality is working fine, what I am unable to get is, right parameters into the url. As I am only passing $sorts to the component, as a prop, hence I'm using this.$inertia.get to pass the $sorts back to the controller, which is returning back the sorted data. But due to passing sorts: this.sorts within the Inertia get method, its returning back the url query as http://127.0.0.1:8000/users?sorts[name]=asc. How can I get the required parameter within the Inertia get method so I get a url query as suchhttp://127.0.0.1:8000/users?sort_field=name&sort_direction=asc as well as pass the $sorts as well so it returns back the expected data.
Controller
public $sorts = [];
public function initalizeSortingRequest()
{
$this->sorts = request()->get('sorts', $this->sorts);
}
public function applySorting($query)
{
foreach ($this->sorts as $sort_field => $sort_direction) {
$query->orderBy($sort_field, $sort_direction);
}
return $query;
}
Component
<script >
methods: {
sortBy(field) {
if (!this.sorts[field]) {
this.sorts[field] = 'asc';
} else if (this.sorts[field] == 'asc') {
this.sorts[field] = 'desc';
} else {
delete this.sorts[field];
}
let route = this.route('users.index', {
sorts: this.sorts
})
this.$inertia.get(route, {}, {
only: ['usersData'],
preserveState: true,
preserveScroll: true
})
}
}
</script>
I recently made a screencast on building a datatable with InertiaJS and Laravel.
The gist of it is:
import AppLayout from '#/Layouts/AppLayout';
import Pagination from '../Jetstream/Pagination';
import { pickBy, throttle } from 'lodash';
export default {
components: {
AppLayout,
Pagination,
},
props: {
users: Object,
filters: Object,
},
data() {
return {
params: {
search: this.filters.search,
field: this.filters.field,
direction: this.filters.direction,
},
};
},
methods: {
sort(field) {
this.params.field = field;
this.params.direction = this.params.direction === 'asc' ? 'desc' : 'asc';
},
},
watch: {
params: {
handler: throttle(function () {
let params = pickBy(this.params);
this.$inertia.get(this.route('users'), params, { replace: true, preserveState: true });
}, 150),
deep: true,
},
},
};
Then in the controller index action:
public function index()
{
request()->validate([
'direction' => ['in:asc,desc'],
'field' => ['in:name,city']
]);
$query = User::query();
if (request('search')) {
$query->where('name', 'LIKE', '%'.request('search').'%');
}
if (request()->has(['field', 'direction'])) {
$query->orderBy(request('field'), request('direction'));
}
return Inertia::render('Users', [
'users' => $query->paginate()->withQueryString(),
'filters' => request()->all(['search', 'field', 'direction'])
]);
}
You can watch the screencast here.

How to update a state array in Vuex?

I need to be able to ADD, REMOVE AND EDIT entries. So far I've only been able to add and remove.
My question is: to add, use PUSH, to remove, use SPLICE. But what about editing?
I am working with VUEJS, VUEX and JavaScript.
Example of what I'm doing:
<b-button type="submit" #click.prevent="submit()">SAVE</b-button>
methods: {
submit() {
this.$v.edit_category.$touch();
if(this.$v.edit_category.$error) return
this.editCategory()
},
editCategory() {
const category = {
value: this.edit_category.value,
text: this.edit_category.text,
category_active: this.edit_category.category_active,
}
this.$store.commit('saveCategory', category)
},
},
store.js:
actions: {
addCategory({ commit }, payload) {
console.log(payload)
commit('addCategory', payload)
},
saveCategory({ commit }, payload) {
console.log(payload)
commit('saveCategory', payload)
},
deleteCategory({ commit }, payload) {
console.log(payload)
commit('deleteCategory', payload)
}
mutations: {
addCategory(state, category) {
state.categories.push(category)
},
saveCategory(state, payload) {
state.categories.push(payload)
},
deleteCategory(state, category) {
var index = state.categories.findIndex(c => c.value === category.value)
state.categories.splice(index, 1)
},
Use Vue.set:
import Vue from 'vue';
// ...
editCategory(state, category) {
var index = state.categories.findIndex(c => c.value === category.value);
Vue.set(state.categories, index, category); // ✅ Vue.set
},
This is needed because reading the docs we see:
Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue

compiler returns: "'value' is defined but never used" when I used it

I want to get in the api with function value and return USD instead of making a lot of functions without value I'm trying this code but compiler returns 'value' is defined but never used
any ideas?
data(){
return {
posts: [],
}
},
methods: {
changeCurrency: function (value) {
axios.get('http://data.fixer.io/api/latest?access_key=509c9d50c1e92a712be9c8f1f964cf67')
.then(response => {
this.currency = response.data.rates.value
})
},
}
<button #click="changeCurrency(USD)">
USD
</button>
data(){
return {
posts: [],
}
},
methods: {
changeCurrency: function () { // removed unused variable "value" here
axios.get('http://data.fixer.io/api/latest?access_key=xxxxxx')
.then(response => {
this.currency = response.data.rates.value
})
},
}
The parameter value is passed to the changeCurrency function but it is never used in the function itself. Your Linter complains about it due to no-unused-vars rule.
data(){
return {
posts: [],
}
},
methods: {
changeCurrency: function () { // <-- removed `value` from here. Should pass the linter
axios.get('http://data.fixer.io/api/latest?access_key=xxxxxx')
.then(response => {
this.currency = response.data.rates.value
})
},
}

Vue.js: mutation for deleting a comment

I have been working on the feature of comment deleting and came across a question regarding a mutation for an action.
Here is my client:
delete_post_comment({post_id, comment_id} = {}) {
// DELETE /api/posts/:post_id/comments/:id
return this._delete_request({
path: document.apiBasicUrl + '/posts/' + post_id + '/comments/' + comment_id,
});
}
Here is my store:
import Client from '../client/client';
import ClientAlert from '../client/client_alert';
import S_Helper from '../helpers/store_helper';
const state = {
comment: {
id: 0,
body: '',
deleted: false,
},
comments: [],
};
const actions = {
deletePostComment({ params }) {
// DELETE /api/posts/:post_id/comments/:id
document.client
.delete_post_comment({ params })
.then(ca => {
S_Helper.cmt_data(ca, 'delete_comment', this);
})
.catch(error => {
ClientAlert.std_fail_with_err(error);
});
},
};
delete_comment(context, id) {
context.comment = comment.map(comment => {
if (!!comment.id && comment.id === id) {
comment.deleted = true;
comment.body = '';
}
});
},
};
export default {
state,
actions,
mutations,
getters,
};
I am not quite sure if I wrote my mutation correctly. So far, when I am calling the action via on-click inside the component, nothing is happening.
Guessing you are using vuex the flow should be:
according to this flow, on the component template
#click="buttonAction(someParams)"
vm instance, methods object:
buttonAction(someParams) {
this.$store.dispatch('triggerActionMethod', { 'something_else': someParams })
}
vuex actions - Use actions for the logic, ajax call ecc.
triggerActionMethod: ({commit}, params) => {
commit('SOME_TRANSATION_NAME', params)
}
vuex mutations - Use mutation to make the changes into your state
'SOME_TRANSATION_NAME' (state, data) { state.SOME_ARG = data }

Vuex syntax error with localcomputed function in combination with getter and setter

I get syntax error when combining Vuex localcomputed object with get/set together with store mappings.
As seen in the Vuex docs you can map your store methods like this with the object spread operater like:
computed: {
localComputed () { /* ... */ },
// mix this into the outer object with the object spread operator
...mapState({
// ...
})
}
https://vuex.vuejs.org/en/state.html##object-spread-operator
Also you can create computed setters like:
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
https://v2.vuejs.org/v2/guide/computed.html#Computed-Setter
I can create either a computed object with get set or have mapState/mapGetters etc. - but not in combination. It break the syntax (error is: expected function name after the function declarations).
computed: {
localComputed () {
localMethod: {
get: function () {
// retrieve
},
set: function (newContent) {
// set
}
}
}, ...mapState([
]), ...mapGetters([])
}
How do i combine these two?
You are trying to define localMethod inside localComputed.
In the docs, localComputed is just an example name for a computed property in your component. You don't have to put all of your other local computed properties within it.
Therefore, you should be able to do the following:
computed: {
localComputed: {
get: function () {
// retrieve
},
set: function (newContent) {
// set
}
},
anotherLocalComputed: {
get: function () {
// retrieve
},
set: function (newContent) {
// set
}
},
...mapState([]),
...mapGetters([])
}
Here is the working sample. I have been using this approach for more than a year
// in some utils/vuex.js file
export const mapSetter = (state, setters = {}) => (
Object.keys(state).reduce((acc, stateName) => {
acc[stateName] = {
get: state[stateName],
};
// check if setter exists
if (setters[stateName]) {
acc[stateName].set = setters[stateName];
}
return acc;
}, {})
);
In your component.vue file
import { mapSetter } from 'path/to/utils/vuex.js';
...
export default {
name: 'ComponentName',
computed: {
...mapSetter(
mapState({
result: ({ ITEMS }) => ITEMS.result,
total: ({ ITEMS }) => ITEMS.total,
current: ({ ITEMS }) => ITEMS.page,
limit: ({ ITEMS }) => ITEMS.limit,
}),
{
limit(payload) {
this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
},
},
)
},
}
now v-model binding should work.

Categories

Resources