Accessing child objects in JavaScript - javascript

'tI am extending two JavaScript objects where one is a variable ajaxed in from a file and the other is a simple object with user preferences.
// local prefs
var prefs = { name: "Bob Barker", show: "Price is Right" };
// ajax in default prefs with dataType: "script"
var defaultPrefs = {
studio: { name: "CBS", location: "Hollywood, CA" },
producers: [ { name: "Producer1" }, { name: "Producer2" } ]
}
// merge prefs
var mergedPrefs = $.extend( prefs, defaultPrefs );
The problem is I can't access the producers or studio using prefs.producers or prefs.studio as they are Objects in the merged file. How can I get around this?

Try this:
var mergedPrefs = $.extend({}, prefs, defaultPrefs);
Extending an empty object will create a new copy of the original object(s).
You can also use Object.assign for the same task, however jQuery.extend also has a deep option to merge recursively whereas Object.assign is always flat (for better performance).

Try this code, but I recomend Object.assign in ES6 to don't use JQuery. Is the same:
var mergedPrefs = Object.assign({}, prefs, defaultPrefs);
Snippet with your code working without Object.assign (using $.extend):
// local prefs
var prefs = {
name: "Bob Barker",
show: "Price is Right"
};
// ajax in default prefs with dataType: "script"
var defaultPrefs = {
studio: {
name: "CBS",
location: "Hollywood, CA"
},
producers: [{
name: "Producer1"
}, {
name: "Producer2"
}]
}
// merge prefs
var mergedPrefs = $.extend({}, prefs, defaultPrefs);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Access object property that is outside of array

My page object is structured so that I have all of the elements in an object and then an array of objects containing data about the fields that can be looped over to test max char length and error texts.
I would like the locator to reference a property that is outside the array so that the value does not need to be updated twice if the element changed.
Snippet from page object as an example...
module.exports = {
siteName: element(by.id('P662_NAME')),
fields: [
{
name: 'site name',
max: 45,
locator: element(by.id('P662_NAME'))
}
]
}
I have tried using the following with no luck...
this.siteName, this.siteName, module.exports.siteName
Is there a way to do this?
Your exporting looks pretty good. Import it correctly.
What you could do is set siteName as another variable and reference that in your fields object like this:
let siteName = "foo"; // now, updating this variable will also update the one in fields
let fields = [{
// other props
locator: siteName
}];
console.log(fields[0].locator); // expects "foo"
// module.exports = { siteName, fields };
Try this :
Export from a file like this
Sandbox: https://codesandbox.io/s/compassionate-bas-fg1c2
var siteName = "dsdsd";
var fields = [
{
name: "site name",
max: 45,
locator: "dsdsd"
}
];
module.exports = {
siteName,
fields
};;
Get it imported like this:
import { siteName } from "./test.js";
console.log(siteName);

How to deserialize the data using JSONAPI-Serializer module of NodeJs

I am working with nodejs and using module named "JSONAPI-Serializer" for serialization and deserialization purpose.
I am able to serialize the objects without any issue but not able to deserialize the same serialized data.
So,using below code I am able to serialize the data:
root#test$: node test.js
var data = [{ id: 1},{ id: 2 }];
var JSONAPISerializer = require('jsonapi-serializer').Serializer;
var UserSerializer = new JSONAPISerializer('id', {"test":"me"});
var users = UserSerializer.serialize(data);
console.log("Serialized:\n", UserSerializer.serialize(data));
Below is the generated result for the same:-
Serialized:
{ data: [ { type: 'ids', id: '1' }, { type: 'ids', id: '2' } ] }
But on deserialization, I am not able to make it work trying to perform the same example as documented in document of "JSONAPI-Serializer".
Can anyone tell me the way to deserialize the above data using "JSONAPI-Serilizer" ?
You're missing your deserialization code. Here is mine that works.
The issue what missing "attributes" option for serializer.
var data = [{ id: 1},{ id: 2 }];
var JSONAPISerializer = require('jsonapi-serializer').Serializer;
var JSONAPIDeserializer = require('jsonapi-serializer').Deserializer;
var UserSerializer = new JSONAPISerializer('id', {attributes: ['id']});
var users = UserSerializer.serialize(data);
console.log(users)
var UserDeserialize = new JSONAPIDeserializer();
UserDeserialize.deserialize(users)
.then(a => console.log(a))

How to make JSData save an instance property to localStorage

How can I make JSData update a modified object that is saved to localStorage?
The code below saves a Tree object with two apples saved to it in a container object. Now updating that container and saving it 'mixes in to the existing instances' as stated in the docs here.
Q: How can I prevent this mixin behavior so the object contains just one apple after saving?
Plunker
var adapter = new DSLocalStorageAdapter();
var store = new JSData.DS();
store.registerAdapter('localstorage', adapter, { default: true });
var Tree = store.defineResource('tree');
Tree.create({
id: 1,
apples: {1: 'one', 2: 'two'}
}).then(function(tree){
tree.apples = {1: 'one'}
tree.DSSave().then(function(tree){
console.log(tree.apples) //
})
});
You're looking for the onConflict option, which defaults to "merge".
This ought to do it:
tree.apples = {1: 'one', 2: null};
tree.DSSave({ onConflict: 'replace' })
.then(function (tree){
console.log(tree.apples);
});
2.x: http://www.js-data.io/v2.9/docs/dsdefaults#onconflict
3.x: http://api.js-data.io/js-data/latest/Collection.html#onConflict

dynamic json to combobox dojo

I have a problem with filling a Combobox dynamic with a jsonRest from a cross Origin request.
I found a chance to do it static (I hope this is the right vocabulary), but I don’t figured out how to do it for more than one case.Because this is a little part of a bigger Website with five Comboboxes.
Here's the Code
require([
"dojo/_base/array",
"dojo/store/Memory",
"dojo/store/JsonRest",
"dijit/form/ComboBox",
"dojo/store/Cache",
"dojo/store/Observable",
"dijit/form/Textarea",
"dojo/domReady!"
],
function(array, Memory, JsonRest, ComboBox, Cache, Observable, Textarea){
var myArray = new Array;
var myStore = new Observable (new Cache (new JsonRest ({
target: “URL / target”,
idProperty: "WA",
headers: { "X-Requested-With": "" }
}), new Memory ()));
var myTextarea = new Textarea ({
name: "myarea",
style: "width:200px;"
}, "myarea");
myStore.query().then(function(response){
});
store = new Memory({data: myArray}); //Store anlegen ... mit Array befüllen
var comboBoxWA = new ComboBox({
id: "comboWA",
name: "WA",
value: "",
store: store, // übergabe angelegter Store zu Combobox
searchAttr: "WA"
}, "comboWA");
// Array befüllen,.. Store anlegen,... Array dem Store zuweisen
myStore.query().then(function(response){
dojo.forEach( response, function( obj ) {
for (var p in obj) {
if(p=="WA"){
//Here is my Problem, I can’t change the “WA” in myArray.push to some global Variable.
myArray.push({"WA" : obj[p]}); //Array befüllen
console.debug(myArray.toSource());
}}
});
});
});
The json response looks like this
[Object { WA=‘'WA_30_14"}, Object { WA="WA_30_12"} , Object { WA="WA_30_10"}, Object { WA="WA_30_16"},…]
Have anybody an Idea or a simple example for me?
Thanks, Georg
You can also try the below method. so you require "myArray.push({"WA" : obj[p]});" to be "myArray.push({some_global_variable: obj[p]});".
do the following.
1.create an empty LOCAL object before the push method
2.Use the array syntax for assiging the property to the local variable
3.Pass the local variable as parameter to the push method.
var localobj = {}; // step 1
localobj[global_var] = obj[p]; //step 2
myArray.push(localobj); // step 3
You can check the value of the global variable before using push() using
console.log("My glogbal varible"+global_var);

Foreign key populated with an object

I would like to make a relation between two models User and Task using backbone-relational.
The relation between the two models is the following:
taskModel.creator_id = userModel.id
// TaskModel
var TaskModel = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasOne,
key: 'creator',
keySource: 'creator_id',
relatedModel: Users
}
],
// some code
});
// Task collection
var TaskCollection = Backbone.Collection.extend({
model: TaskModel,
// some code
});
// User Model
var User = Backbone.RelationalModel.extend({
// some code
});
Actually the problem is in the collection.models, please see the attached images:
Please check this jsfiddle: http://jsfiddle.net/2bsE9/5/
var user = new User(),
task = new Task(),
tasks = new Tasks();
task.fetch();
user.fetch();
tasks.fetch();
console.log(user.attributes, task.attributes, tasks.models);
P.S.:
Actually I am using requireJs to get the UserModel, so I cannot include quotes in relatedModel value.
define([
'models/user',
'backbone',
'relationalModel'
], function (User) {
"use strict";
var Task = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasOne,
key: 'creator',
keySource: 'creator_id',
relatedModel: User
}
],
});
);
Edit 2:
http://jsfiddle.net/2bsE9/13/
I updated the jsfiddle to reflect the changes I suggested below. As long as you are calling toJSON on your task, what gets to the server is a json object with the creator_id property set to the actual id of the user. The keyDestination here is redundant as the documentation states it is set automatically if you use keySource.
Edit:
https://github.com/PaulUithol/Backbone-relational#keysource
https://github.com/PaulUithol/Backbone-relational#keydestination
https://github.com/PaulUithol/Backbone-relational#includeinjson
The combination of the three above might solve your issue.
var Task = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasOne,
// The User object can be accessed under the property 'creator'
key: 'creator',
// The User object will be fetched using the value supplied under the property 'creator_id'
keySource: 'creator_id',
// The User object will be serialized to the property 'creator_id'
keyDestination: 'creator_id',
// Only the '_id' property of the User object will be serialized
includeInJSON: Backbone.Model.prototype.idAttribute,
relatedModel: User
}
],
});
The documentation also states that the property specified by keySource or keyDestination should not be used by your code. The property cannot be accessed as an attribute.
Please try this and comment if that fixes your issue.
Btw, here is a nice blog post that uses backbone-relational end to end.
http://antoviaque.org/docs/tutorials/backbone-relational-tutorial/
Edit
Updated jsfiddle
The problem is that Backbone-Relational explicitly deletes the keySource to 'prevent leaky abstractions'. It has a hardcoded call to unset on the attribute, in Backbone-Relational:
// Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
if ( this.key !== this.keySource ) {
this.instance.unset( this.keySource, { silent: true } );
}
You will need to overwrite the unset method in your Task model:
var Task = Backbone.RelationalModel.extend({
urlRoot: ' ',
relations: [
{
type: Backbone.HasOne,
key: 'creator',
relatedModel: User,
keySource: 'creator_id'
}
],
unset: function(attr, options) {
if (attr == 'creator_id') {
return false;
}
// Original unset from Backbone.Model:
(options || (options = {})).unset = true;
return this.set(attr, null, options);
},
sync: function (method, model, options) {
options.success({
id: 1,
name: 'barTask',
creator_id: 1
});
}
});
Obvious problems with this approach are that you will need to modify your code if either Backbone changes its Backbone.Model.unset method or Backbone-Relational changes its keySource behavior.

Categories