I just created a constructor function to create new Users for a JSON file.
The structure should be like:
{
"users": {
"userName1": {
"salary": [
"1234"
]
},
"userName2": {
"salary": [
"4321"
]
}
}
}
My code looks like this atm:
export const userDataControllerMixin = {
data() {
return {
userObj: {},
};
},
methods: {
NewUser(user, salary) {
this.user = user;
this.salary = salary;
user = {
salary,
};
},
// GETTING INPUT FROM USERS DIALOGBOX
getInput(inputName, inputSalary) {
const userName = document.querySelector(inputName).value;
const userSalary = document.querySelector(inputSalary).value;
const userData = new this.NewUser(userName, userSalary);
console.log(userData);
},
The structur i get is wrong, it looks like this:
NewUser {user: "asd ", salary: "123"}
When you use the word this, it means the current father, in your case NewUser
To get the variable the way you want, you need to do this:
NewUser(user, salary) {
this[user] = {
'salary':salary
};
},
In VueJS there is no need for querySelectors, since inputs are binded with v-model
Check out: https://v2.vuejs.org/v2/guide/forms.html
Because of that, we can reduce the app to one function, that reads the username and salary properties and adds them to the userObj.
I've made a working example here: https://codepen.io/bergur/pen/agZwQL?editors=1011
new Vue({
el: '#app',
data() {
return {
username: '',
salary: '',
userObj: {}
}
},
methods: {
newUser() {
this.userObj[this.username] = {
salary: [Number(this.salary)]
}
console.log(this.userObj)
}
}
})
Related
I have the following code:
const { query1 } = require('query1')
const { query2 } = require('query2')
const { query3 } = require('query3')
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: "Query",
fields: {
query1,
query2,
query3
}
})
});
const permissions = shield(
{
Query: {
query1: user,
query2: user,
query3: admin
}
}
)
(much longer in the reality)
And I'm looking for a way to make it clearer, like:
const { query1 } = require('query1')
const { query2 } = require('query2')
const { query3 } = require('query3')
const declaration = {
query1: user,
query2: user,
query3: admin
}
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: "Query",
fields: someMagic(declaration)
})
});
const permissions = shield(
{
Query: declaration
}
)
But here declaration keys are the strings "query1", "query2" and "query3". Not the objects.
With a WeakMap we could have something like:
const declaration = new WeakMap();
declaration.set(query1, user);
declaration.set(query2, user);
declaration.set(query3, admin);
But I find it much less elegant. Is there another way ?
Hope this might help:
/*
queries['query1'] = require('query1')
queries['query2'] = require('query2')
queries['query3'] = require('query3')
*/
let queries = {
query1: { a: { $eq: "I am Query 1" }, permission: "user" }, //user can be String or object or whatever !
query2: { b: { $eq: "I am Query 2" }, permission: "user" },
query3: { c: { $eq: "I am Query 3" }, permission: "admin" },
};
let declaration = {};
let queryNames = Object.keys(queries);
for (let i in queryNames) {
let curQueryName = queryNames[i];
declaration[curQueryName] = queries[curQueryName]["permission"];
//delete queries[curQueryName]["permission"]
}
console.log(JSON.stringify(declaration, null, 2));
Instead of an object, you could have an array of objects, something like this:
const { query1 } = require('query1')
const { query2 } = require('query2')
const { query3 } = require('query3')
var declarations = [
{ query1, permissions: user },
{ query2, permissions: user },
{ query3, permissions: admin }
];
Then to extract fields and permissions objects:
var fields = {};
var queryPermissions = {};
for (let declaration of declarations) {
for (let key of Object.keys(declaration)) {
if (key !== 'permissions') {
fields[key] = declaration[key];
queryPermissions[key] = declaration.permissions;
}
}
}
For example:
const query1 = { query: 'sample query 1' };
const query2 = { query: 'sample query 2' };
const query3 = { query: 'sample query 3' };
const user = 'user';
const admin = 'admin';
var declarations = [
{ query1, permissions: user },
{ query2, permissions: user },
{ query3, permissions: admin }
];
var fields = {};
var queryPermissions = {};
for (let declaration of declarations) {
for (let key of Object.keys(declaration)) {
if (key !== 'permissions') {
fields[key] = declaration[key];
queryPermissions[key] = declaration.permissions;
}
}
}
console.log(fields);
console.log(queryPermissions);
Side Note:
Another advantage of doing it this way is that you can group queries by permissions, for instance:
var declarations = [
{ query1, query2, permissions: user },
{ query3, permissions: admin }
];
It's not possible to construct an object that uses a variable's name as the property name but something else than the variable's value as the value. You'll have to spell them out twice, once for the permissions once for the resolvers:
const queryPermissions: {
'query1': user,
'query2': user,
'query3': admin,
};
const queryResolvers: {
'query1': require('query1').query1,
'query2': require('query2').query2,
'query3': require('query3').query3,
};
The destructured variables from the imports don't really help with anything here. However, if your module structure is really like this, and you're still using Common.js modules, then you can actually derive the queryResolvers object from the property names of the queryPermissions object:
const queryResolvers = Object.fromEntries(Object.keys(queryPermissions).map(fieldName =>
[fieldName, require(fieldName)[fieldName]]
));
This should do the trick:
((function(t,d){
var fields = {}
for (const key in d) {
fields[key] = t[key]
}
return fields
})(this, declaration)
{a, b, c}
Is just shorthand for {a: a, b: b, c: c}
However, Global constants do not become properties of the window object, unlike var variables, so you might need to fiddle a bit with it.
I have a nested array of objects like this:
var posts = [
{
_id:1234,
body:"text",
comments:[
{
_id:234,
body:"hello world", {
]
},
{
_id:434,
body:"hello world",
replies:[
{
_id:0e2345,
body:"hello",
{
]
}
]
}
]
I want to use normalizr to simplify array and use with redux. I have read the Normalizr documentation but it has few examples and I do not know what I am doing wrong.
I have tried the following code without success. The result I get is an array with undefined.
export function getPosts(state, action) {
const { payload } = action;
const { data} = payload;
const normalized = new schema.Entity("posts", {}, { idAttribute: "_id",});
const normalizedData = normalize(data, [normalized]);
return {
...state,
normalizedData,
};
}
I need something like this:
entities:{
posts:{
123:{
_id:123,
body:"hello world",
comments:{
234:{
_id:234,
body:"hello world",
replies:{
0e2345:{
_id:0e2345,
body:"oh no"
}
}
}
}
}
}
}
I've tried to reproduce this using a JSON object:
[{
"_id":1234,
"body":"text",
"comments":[
{
"_id":234,
"body":"hello world" }
]
},
{
"_id":434,
"body":"hello world",
"replies":[
{
"_id":0e2345,
"body":"hello"
}
]
}
]
And making the structure in the code:
import data from "./data.json";
import { normalize, schema } from "normalizr";
const _id = new schema.Entity('_id');
const body = new schema.Entity('body');
const normalized = new schema.Entity("posts", {
posts:{
_id:{
_id:_id,
body:body,
comments:{
_id:{
_id:_id,
body:body,
replies:{
_id:{
_id:_id,
body:body
}
}
}
}
}
}
});
const normalizedData = normalize(data, [normalized]);
console.log(normalizedData);
I get the next console output.
My app has a feature where users can filter results based on "blood group" and "city", and areas. Results will be retrieved from DB using Axios for Vuejs through "URL" query strings. Example url is: http://example.com/api/results?blood=a+&city=london
It should work in a way that when a user select just blood group from select menu: the url would exclude the city parameter. But from my current code, I can't get it stripped of, as a result, the database query returns no results on the basis that cityreturns null value.
Here's what I have in my Vue component:
<script>
export default {
props: ['user'],
data() {
return {
auth_user: this.user,
results: {},
blood_groups: "",
cities: "",
districts: "",
areas: "",
donorUrl: "/api/donors",
requestedBlood: "",
requestedCity: "",
requestedDist: "",
requestedArea: "",
params: {}
};
},
created() {
this.fetchDonors();
this.fetchCities();
},
methods: {
fetchDonors() {
let url = "/api/donors";
axios.get(url).then(response => {
this.results = response.data.data;
this.blood_groups = [...new Set(response.data.data.map(x=> x.blood_group))];
});
},
fetchCities() {
let url = "/api/location_type/cities";
axios.get(url).then(response => {
this.cities = response.data.cities
})
},
selected_blood_group(event) {
this.requestedBlood = event.target.value;
this.get();
},
get_city(event) {
this.requestedCity = event.target.value;
this.get();
},
get() {
let request = {
params: {
blood: this.requestedBlood,
city: this.requestedCity,
dist: this.requestedDist,
area: this.requestedArea
}
}
axios.get('/api/donors', request).then(response => {
this.results = response.data.data
})
}
},
};
</script>
My query is how can I remove or check if any of the following properties contains empty value, so that I do not include them in axios params?
let request = {
params: {
blood: this.requestedBlood,
city: this.requestedCity,
dist: this.requestedDist,
area: this.requestedArea
}
}
You can try below code.
Create a new object(called testParams) and add that object in params.suppose requestedCity is selected(not only but any variable is selected ). Then you can do like below.
if(requestedCity.length!=0)
{
testParams["city"]=requestedCity; // OTHERWISE DON'T ADD IN testParams object
}
Finally while making request through axios add testParams in params object like below.
axios.get('/yourUrl/',{
params:{
testParams //here vue will automatically sets 'testParams':testParams
}
})
I got it working with the following approach:
let request = {
blood: this.requestedBlood,
city: this.requestedCity,
dist: this.requestedDist,
area: this.requestedArea
}
for(let k in request)
if(!request[k]) delete request[k];
axios.get('/api/donors', {
params: request
}).then(response => {
this.results = response.data.data
})
I have a class "House" like :
class House{
constructor(params){
this.clear();
// this = {...params} // I know that don't work !!!
//--
// if(params.address !== undefined) this.address = {...params.address}
//...
}
clear(){
this.address = {
number: null,
street: null,
zipcode: null,
ton: null,
}
this.access = {
doorcode: null,
stair: null,
}
}
}
I want to create a new instance of House and inject in constructor multiple json like :
const h = new House({address: { /* json */ }, access: { /* json */});
Or only one like :
const h = new House({access: { /* json */});
In constructor, am i obliged to check all values in "params" to insert in good properties (nested object)
I would like to avoid to create other classes like address and access and in the house constructor create new instance of each.
What's the best practice ?
Regards
Using Object.assign() and object destructuring with default parameters in the constructor, you can achieve this quite easily:
class House {
static get defaultAddress () {
return {
number: null,
street: null,
zipcode: null,
town: null
}
}
static get defaultAccess () {
return {
doorcode: null,
stair: null
}
}
constructor({ address = House.defaultAddress, access = House.defaultAccess } = {}) {
this.clear()
Object.assign(this.address, address)
Object.assign(this.access, access)
}
clear () {
const { defaultAddress, defaultAccess } = House
Object.assign(this, { address: defaultAddress, access: defaultAccess })
}
}
// no object
console.log(new House())
// empty object
console.log(new House({}))
// partial object
console.log(new House({ address: { number: 1, street: 'street', zipcode: 12345, town: 'town' } }))
// empty sub-objects
console.log(new House({ address: {}, access: {} }))
// partial sub-objects
console.log(new House({ address: { number: 1, street: 'street' }, access: { doorcode: 321 } }))
// complete object
console.log(new House({ address: { number: 1, street: 'street', zipcode: 12345, town: 'town' }, access: { doorcode: 321, stair: 3 } }))
.as-console-wrapper{min-height:100%!important}
You can loop through the parameters and set them manually. Then, to clear, remove all own properties (properties that aren't inherited).
class House {
constructor(params) {
// set data
Object.assign(this, params);
}
clear() {
for (let key in this) {
if (this.hasOwnProperty(key))
this[key] = undefined; // or `delete this[key];`
}
}
}
let house = new House({type: "normal", height: 40});
console.log(house, house instanceof House);
Of course, you probably want to limit the input keys to a predefined set. You could store those keys in a static class variable and use them to loop through the properties in constructor and clear.
class House {
constructor(params) {
// check for invalid properties
Object.keys(params).forEach(key => {
if (!House.keys.includes(key))
throw `Invalid paramater ${key}`;
});
// set data
Object.assign(this, params);
}
clear() {
for (let key in House.keys) {
if (this.hasOwnProperty(key))
this[key] = undefined; // or `delete this[key];`
}
}
}
House.keys = ['type', 'height'];
let house = new House({type: 'normal', height: 40});
console.log(house, house instanceof House);
let error = new House({helloWorld: true});
I think you want a common namespace for your instance properties - similar to React's props pattern - you can also specify defaults for each instance you are creating:
const defaultProps = { address: {}, access: {} };
class House {
constructor(props = {}) {
this.props = {...defaultProps, ...props};
}
clear() {
this.props = {...defaultProps};
}
}
I am having issues setting a variable via ajax.
const store = new Vuex.Store({
state: {
conversationsList: []
},
mutations: {
conversationList(state, payload) {
state.conversationList = payload;
}
}
});
setInterval(function () {
axios.get('/conversation/get-conversations')
.then((response) => {
store.commit('conversationList', response.data);
});
}, 1000);
I cant understand why the state.conversationList = payload does not change the value?
Even replacing the ajax call with a simple array assignment such as
var testList = [
{id: 1, author: 'john', type: 'follower', lastMessage : 'hi'}
];
store.commit('conversationList', testList);
doesnt work