How to add new attribute in data object? - javascript

For arrays vue.js good works with default array methods: push, pop, shift, reverse... But how to create new item in object and paste some value?
new Vue({
el: '#demo',
data: {
items: [
{
start: '12:15',
end: '13:15',
name: 'Whatch Vue.js Laracast',
description: 'Watched the Laracast series on Vue.js',
tags: ['learning', 'Vue.js', 'Laracast', 'PHP'],
note: "Vue.js is really awesome. Thanks Evan You!!!"
},
{
start: '13:15',
end: '13:30',
name: "Rubik's Cube",
description: "Play with my Rubik's Cube",
tags: ['Logic', 'Puzzle', "Rubik's Cube"],
note: "Learned a new algorithm."
}
],
},
methods: {
addItemAttribute: function(name, text) {
this.items[0][name] = text;
}
}
});

You can add properties to a Vue object similar to a normal javascript object. Reference: https://vuejs.org/api/#Options-Data
var obj = { a: 1};
obj.a // 1
obj.b // undefined
obj.b = 2;
// Now obj.b is defined
obj.b // 2
You can access data from Vue object like this
var vm = new Vue({
data: {
a: 1,
b: 2
}
});
Now we can access data from $data property
vm.$data.a === 1;
// You can add a new property
vm.$data.c = 3;
// it can be any object
vm.$data.d = {id: 1, name: 'ABC'}
You get and update props of a component using component.options.props
var component = Vue.component('props-demo-advanced', {
props: {
// just type check
size: Number,
// type check plus other validations
name: {
type: String,
required: true,
// warn if not two way bound
twoWay: true
}
}
});
Let's say, we want to make name twoWay binding to false
component.options.props.name.twoWay = faslse
Or even you can change the entire object.
component.options.props = {
size: Number,
type: {
type: Number,
required: false,
twoWay: false
}
}
I don't know the above configurations are correct or not, I am just trying to convey the idea.
You should learn Javascript first, how objects are made, how to change them etc.

Related

Meter push new object to array in collection

I am trying to update a collection by pushing to an already existing array in the collection.
Here is the update function I am trying to run:
Games.update({ _id: game._id }, {
$push: { players: { name: playerName } },
});
Here is the error I am getting in the console:
update failed: MongoError: Cannot update 'players' and 'players' at the same time
Relevant schemas:
Player = new SimpleSchema({
name: {
type: String,
label: 'name',
max: 50,
},
});
Schemas.Game = new SimpleSchema({
...
players: {
type: [Player],
label: 'Players',
autoValue: function () {
return [];
},
},
});
I am using the autoValue for the players array to sort of initialize it when a new game is created. Could this be a problem for when the first player is added?
Some help would be appreciated.
Edited: #Logiwan992 try using defaultValue instead of autoValue.I believe you're using autoValue to set the value of players so it isn't undefined. But with your implementation, autoValue would run when there is an update on your document.
defaultValue would run when the document is created first. But if you still choose to use autoValue, you may also want to check if it's an update and return undefine. As in this
players: {
type: [Player],
label: 'Players',
autoValue: function () {
if (this.isUpdate) {
return undefined;
}
return [];
},
},
Returning undefined would ensure the new update value is used.
My recommendation though is to use
players: {
type: [Player],
label: 'Players',
defaultValue: [],
},

Creating a mongoose model containing array types return undefined for those in my docker container

I have a mongoose model containing 2 properties Array of String and some others:
var Model = new Schema({
_id: {type: Number, required: true, unique: true},
name: {type: String, required: true},
oneList: [String],
anotherList: [String]
});
I create the model:
var model = new Model({
_id: 1,
name: 'model',
oneList: ['a', 'b'],
anotherList: ['c', 'd']
})
but when I inspect the model all the list are undefined:
model._doc === {
_id: 1,
name: 'model',
oneList: undefined,
anotherList: undefined
}
I tried some variations:
change the model definition from [String] to [ ]
create separately the data outside the model then pass it
create the model without list data then add it to the model
Even when I create an empty model:
var model = new Model({})
model._doc.oneList === undefined
model._doc.anotherList === undefined
Context:
The problem occurs on a docker container but not on my local machine
node: v4.4.7
mongoose: v4.6.0
GitHub
I had the same issue, apparently when you have a nested array within your model, mongoose has an open issue 1335 that saves an empty array when a property references a schema. I experimented with presaves to force the property to be an empty array if the property's length is 0 or undefined.
Also be careful when specifying unique=true in the property's schema, as empty or undefined properties will violate the indexing and throw an error.
Note:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var barSchema = new mongoose.Schema({
baz: String
});
var fooSchema = new mongoose.Schema({
bars: [barSchema]
});
var Foo = mongoose.model('Foo', fooSchema);
var foo = new Foo();
console.log(foo); // { _id: 55256e20e3c38434687034fb, bars: [] }
foo.save(function(err, foo2) {
console.log(foo2); // { __v: 0, _id: 55256e20e3c38434687034fb, bars: [] }
foo2.bars = undefined;
foo2.save(function(err, foo3) {
console.log(foo3); // { __v: 0, _id: 55256e20e3c38434687034fb, bars: undefined }
Foo.findOne({ _id: foo3._id }, function(err, foo4) {
console.log(foo4); // { _id: 55256e20e3c38434687034fb, __v: 0, bars: [] }
mongoose.disconnect();
});
});
});
You can do like this:
var schema = new Schema({
_id: {
type: Number,
required: true,
unique: true
},
name: {
type: String,
required: true
},
oneList: [String],
anotherList: [String]
}),
Model = mongoose.model('Model', schema),
m = new Model();
m._id = 1;
m.name = 'model';
m.oneList.push('a', 'b');
m.anotherList.push('c', 'd');

Remove parent object of a JSON if it has certain property

I'm getting a JSON structure from an API, that I want to change in my front end. The frontend adds a property to the JSON structure, "isHidden". When I send the modified JSON back, I don't want the object that has "isHidden" to be sent back to the API, but I will still save that internally in my own mongodb.
However, doing this was aperently a bit harder then I thought. I made this function wich works but I think is very ugly:
function removeHiddenObject(data,parent){
for(var property in data){
if(data.hasOwnProperty(property)){
if(property == "isHidden" && data[property] === true){
parent.splice(parent.indexOf(data), 1);
}
else {
if(typeof data[property] === "object") {
removeHiddenObject(data[property], data);
}
}
}
}
return data;
}
It's a recursive method, but I find it way to complex and weird. Is there a way of simplifying my task?
Here is a jsfiddle for you if you'd like to help out: https://jsfiddle.net/vn4vbne8/
use this code to remove it from json string :
myJson=s.replace(/,*\s*"[^"]"\s*\:\s*{(.*?)"isHidden"\:([^}]*)}/gm,"");
Be careful in Regex every character is important so use exactly above code.
It removes every property that have an object that one of its properties is isHidden.
Javascript actually supports non-enumerable public properties. I'm assuming that when you send data back to the server you first stringify it with JSON.stringify which will only stringify public enumerable properties of the object.
You can define a non-enumerable property like this (more on this here):
Object.defineProperty(obj, 'isHidden', {
enumerable: false,
writable: true
});
Where obj is the javascript object you want to add the property to and isHidden is the name of the property you are adding. When done this way, the new property is accessible as obj.isHidden but nevertheless will not show up in JSON.stringify output nor in for loops.
Here is a solution using object-scan. Takes a bit of time to wrap your head around it, but it helps with some heavy lifting around general data processing.
// const objectScan = require('object-scan');
const data = {"user":{"name":"Bob"},"buildingBlockTree":[{"uid":"a875ed6cf4052448f9e0cc9ff092a76d4","_id":"56a7353f682e1cc615f4a6ae","columns":[{"uid":"a0061fdd2259146bb84e5362eeb775186","_id":"56a7353f682e1cc615f4a6b1","buildingBlocks":[{"user":{"name":"lajdi"},"buildingBlockTree":[{"uid":"a875ed6cf4052448f9e0cc9ff092a76d4","_id":"56a7353f682e1cc615f4a6ae","columns":[{"uid":"a0061fdd2259146bb84e5362eeb775186","_id":"56a7353f682e1cc615f4a6b1","buildingBlocks":[]},{"uid":"abbcf3328854840deb96bb6b101df2b39","_id":"56a7353f682e1cc615f4a6af","buildingBlocks":[{"uid":"a931cf745d4b847ba9cdc7f4b830413be","_id":"56a7353f682e1cc615f4a6b0","source":{"limit":1,"itemsListId":1,"offset":0}}]}],"template":{"name":"Xs12Sm12Md6Lg12DotXs12Sm12Md6Lg12"}}],"_id":"56a7353f682e1cc615f4a6ad","source":{"limit":1,"itemsListId":1,"offset":0},"template":{"numberOfColumns":1},"uid":"a5f6a2fd1c80f49c0b97e0c7994400588"}]},{"uid":"abbcf3328854840deb96bb6b101df2b39","_id":"56a7353f682e1cc615f4a6af","buildingBlocks":[{"_id":"56a7353f682e1cc615f4a6b0","source":{"limit":1,"itemsListId":1,"offset":0},"isHidden":true}]}]}],"_id":"56a7353f682e1cc615f4a6ad","source":{"limit":1,"itemsListId":1,"offset":0},"uid":"a5f6a2fd1c80f49c0b97e0c7994400588","metadata":{"title":"sss"},"title":"sss","url":"sss"};
const removeHiddenObjects = (input) => objectScan(['**[*].isHidden'], {
rtn: 'count',
filterFn: ({ value, gparent, gproperty }) => {
if (value === true) {
gparent.splice(gproperty, 1);
return true;
}
return false;
}
})(input);
console.log(removeHiddenObjects(data)); // counts removals
// => 1
console.log(data);
/* => {
user: { name: 'Bob' },
buildingBlockTree: [ {
uid: 'a875ed6cf4052448f9e0cc9ff092a76d4',
_id: '56a7353f682e1cc615f4a6ae',
columns: [ {
uid: 'a0061fdd2259146bb84e5362eeb775186',
_id: '56a7353f682e1cc615f4a6b1',
buildingBlocks: [ {
user: { name: 'lajdi' },
buildingBlockTree: [ {
uid: 'a875ed6cf4052448f9e0cc9ff092a76d4', _id: '56a7353f682e1cc615f4a6ae', columns: [
{ uid: 'a0061fdd2259146bb84e5362eeb775186', _id: '56a7353f682e1cc615f4a6b1', buildingBlocks: [] },
{ uid: 'abbcf3328854840deb96bb6b101df2b39', _id: '56a7353f682e1cc615f4a6af', buildingBlocks: [
{ uid: 'a931cf745d4b847ba9cdc7f4b830413be', _id: '56a7353f682e1cc615f4a6b0', source: {
limit: 1,
itemsListId: 1,
offset: 0
} }
] }
],
template: { name: 'Xs12Sm12Md6Lg12DotXs12Sm12Md6Lg12' }
} ],
_id: '56a7353f682e1cc615f4a6ad',
source: { limit: 1, itemsListId: 1, offset: 0 },
template: { numberOfColumns: 1 },
uid: 'a5f6a2fd1c80f49c0b97e0c7994400588'
} ]
}, { uid: 'abbcf3328854840deb96bb6b101df2b39', _id: '56a7353f682e1cc615f4a6af', buildingBlocks: [] } ]
} ],
_id: '56a7353f682e1cc615f4a6ad',
source: { limit: 1, itemsListId: 1, offset: 0 },
uid: 'a5f6a2fd1c80f49c0b97e0c7994400588',
metadata: { title: 'sss' },
title: 'sss',
url: 'sss'
}
*/
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#16.0.0"></script>
Disclaimer: I'm the author of object-scan

Nested Javascript Object : recursion and "complex" transformation (with lodash)

I apologize in advance for the complex example here; I tried to trim it down as much as I could to illustrate what I try to achieve
I have a complex structure that I need to traverse and transform based on some conditions; Here's an (short) example of the structure that should cover most scenarios:
{ PROP1: {
metadata: Object, // somewhere deeper in metadata I have a `value` key
parent: { $ref: String },
employee: {
parent: { $ref: String },
id: String,
metadata: Object,
products: {
metadata: Object,
model: { $ref: String },
type: 'array',
value: ["String", "String" , "String"] ,
[...]
},
model: {
id: String,
email: {
metadata: Object,
value: 'a#b.com',
type: 'string',
validity: Object,
[...]
},
name: {
firstName: {
metadata: Object,
value: 'John',
type: String,
validity: Object,
[...]
},
lastName: {
metadata: Object,
value: 'Smith',
type: String,
validity: Object,
[...]
},
}
},
operations: {
id: String,
items: [
{ action: {value: "UPDATE", model: {$ref: String }, [...] },
{...}
],
metadata: Object,
[...]
}
}
},
PROP2: {
// similar as PROP1
},
[... and so on ...]
}
I basically need to clean that up before sending it to the backend;
Whenever a value contains $ref, I don't want the key/val pair (e.g.: PROP1.parent is of no use and can be omitted)
whenever a value contains value, I need to omit everything else and move the value of value as the value of key (e.g.: PROP1.employee.products should equal ['String', 'String', 'String'])
keys like id, metadata, validity (etc) can be completely omitted regardless of its content
So the end result should be along those lines:
{ PROP1: {
employee: {
products: ['item','item','item'],
model: {
email: 'a#b.com',
name: { firstName: 'John', lastName: 'Smith'},
},
operations: [
{action: 'UPDATE'}
]
}
},
PROP2: { ... }
}
I tried lots of different approaches using different lodash methods but couldn't wrap my head around this...
Any help will be greatly appreciated
Thanks
In pseudo code, try something like this. Implement the specifics and post more info when you run into trouble.
var ignoreKeyArray = ["id", ...] // keys to ignore and remove
var newJSON = "{}";
for (property in JSON) {
var newProp = parseJSON(key, property);
insert newProp in newJSON object
}
var parseJSON = function (key, jsonBlob) {
if (key in ignoreKeyArray || jsonBlob contains value "$ref")
return "";
var jsonOut = key + ": {}";
for (child in jsonBlob) {
add parseJSON(child) to jsonOut;
}
return jsonOut;
}
If you have any questions, comment so I can extend the answer and clarify.

Reference (not copy) a class as a member of another Class - Mootools

I have the following classes
The Box Class
var Box = new Class({
Implements: [Options],
options: {
name: 'new',
weight: 0
},
initialize: function (options) {
this.setOptions(options);
},
getParent: function () {
return this.options.parent;
}
});
The Collection Class
var Collection = new Class({
Implements: [Options],
options: {
boxes: []
},
boxes: [],
initialize: function (options) {
var self = this;
this.setOptions(options);
Array.each(this.options.boxes, function (box) {
self.boxes.push(new Box({
parent: self,
name: box.name,
weight: box.weight
}));
});
}
});
I am passing the Collection class (as the parent) to the Box Class when it is created.
var newCollection = new Collection({
boxes: [
{
name: 'A',
weight: 9
},
{
name: 'B',
weight: 3
},
{
name: 'C',
weight: 2
},
{
name: 'D',
weight: 5
},
{
name: 'E',
weight: 7
}
]
});
I want the parent in the Box class to be a reference to the Collection class and not a copy, although It seems that I get a copy of the newCollection class each time the Box class is created (the length of the boxes is different for each one)
Array.each(newCollection.boxes, function (box) {
console.log('*',box.getParent());
});
I am new to mootools and even though I have gone through the documentation, this is the way I ended up writing code. Is there a more accepted coding pattern in mootools by which I can reference the parent?
Here's the fiddle.
Easy to miss. setOptions (docs) deep copies the options object. Just set the parent property of your Box after initializing it. I've posted a slightly modified version of your code here
Array.each(this.options.boxes, function (box) {
var nB = new Box({
name: box.name,
weight: box.weight
});
// Note the difference
nB.parent = self;
self.boxes.push(nB);
});

Categories

Resources