Parse.com javascript sdk nested save - javascript

I know this was possible in the Java SDK for Parse. But given a situation where I have a parse object A that will point to another object B that will to another object C.
By setting all of their fields correctly is it possible to just save object A and have the nested objects be saved automatically
Thanks,
Karan Shah

Objects in Parse cannot be set to fields until they have been saved.
You need to save C, then B, then A.
This can be achieved with Parse promises.
var C = Parse.Object.extend("C"); // Or whatever objects they are
var B = Parse.Object.extend("B");
var A = Parse.Object.extend("A");
C.save().then(function()
{
B.set("C", C);
return B.save();
}).then(function()
{
A.set("B", B);
return A.save();
}).then(function()
{
console.log("All saved successfully!");
});

Actually as of 2020/1 you can save them all at once.
Use the optional argument in save(opts).
const Child = Parse.Object.extend("Child");
const child = new Child();
const Parent = Parse.Object.extend("Parent");
const parent = new Parent();
parent.save({ child: child });
// Automatically the object Child is created on the server
// just before saving the Parent

Related

How to get data as Object from dataTransfer?

I do the following:
const blockOrField = new Block();
ev.dataTransfer.setData("data", blockOrField);
When I get data in another place:
cosnt data = e.dataTransfer.getData("data");
I get data as [object Object] instead real instrance.
Before passing to data I see that it is instance:
if (blockOrField instanceof FieldDefinition) {
alert("works");
}
ev.dataTransfer.setData("data", blockOrField);
I know it should be serialized to string JSON, but I have complicated instance with composition.
If you look at the documentation for setData() it specifically says "A DOMString representing the data to add to the drag object.". So you are out of luck trying to store an object reference there.
What I would do here is create a another object somewhere and store the needed reference there with an id.
const dataTransferCache = {};
function onDragStart(ev) {
const block = new Block();
const id = GetRandomId(); // Just get an id somehow
dataTransferCache[id] = block;
ev.dataTransfer.setData("data", id);
}
function onDragEnd(ev) {
const id = ev.dataTransfer.getData("data");
const block = dataTransferCache[id];
delete dataTransferCache[id]; // Remove the value again
}
This would even support multi touch dragging if that is somehow needed. If this needs to be shared between components you could simply put the dataTransferCache in a separate file and include a reference to in in both components.

Angular Factory Object Persisting Over Storing in Local Storage

I've got a problem that i need help with in Angular 1.4.0.
I have a factory in angular which has a complex structure and method within so i am able to restore the factory back to its original state by calling the method.
The factory looks like this.
angular.module('myApp').factory('itemFcty', function(){
var currentValues = {};
var default values {
a = 1,
b = 2,
resetData : function(){
currentValues = angular.extend(currentValues, defaultValues);
return currentValues
};
};
defaultValues.resetData();
return currentValues;
});
In order to add values to 'a' i call itemFcty.a = 2;
So this method works well when i want to overwrite all the values as and when required.
However i have been asked could i persist the data over a refresh. So i stringify the object into JSON. Like this:
localStorage.setItem('itemFcty', JSON.parse(itemFcty);
However i have hit a snag. The only data to be stored in the local storage is the
{a = 1,b = 2,}
I can add the method back in by doing this:-
itemFcty.resetData = function(){return currentValues = angular.extend(currentValues, defaultValues);}
This is the issue that now the factory does function the same way as before as i am not able to call the function as the call and return outside the default values object is not there any more i can cannot for the life of me work out how to add it back into as everything goes directly into the object as a whole.
Your help would be greatly appreciated!
/*************************EDIT *****************************/
Ok, so i think that i havent explained the point very well.
My factory looks exactly like the above. The user hits refresh. The factory is stored in local storage. I get it back from local storage. But heres the issue.
It looks like this before local storage
angular.module('myApp').factory('itemFcty', function(){
var currentValues = {};
var defaultValues = {
a : 1,
b : 2,
resetData : function(){
angular.extend(currentValues, defaultValues);
// you don't have to return the values
} // <------you can't use ; in the object properties
};
defaultValues.resetData();
return currentValues;
});
Now when i get the data out f local storage and into the factory the factory then looks like this.
angular.module('myApp').factory('itemFcty', function(){
a : 1,
b : 2,
});
I can add the reset data function back in, however as the factory does not contain current or default values, the reset data function will not work.
So basically i am asking how to make my factory, look the same as it does originally after i have reloaded data from the local storage.
Did you load the variable back from localStorage? Also, there is a typo, I'd say var default values. In general stringifying does not account for methods, because that wouldn't make sense for other languages importing them.
Problems:
var default values {, space separated variable and missing assignment operator =.
In the object you can assign values with = but :, so it will produce error { a = 1, b = 2 }.
what you can do is:
angular.module('myApp').factory('itemFcty', function(){
var currentValues = {};
var defaultValues = { // <-------should have to be declared like this
a : 1, // = should be replaced with :
b : 2, // and here too.
resetData : function(){
angular.extend(currentValues, defaultValues);
// you don't have to return the values
} // <------you can't use ; in the object properties
};
defaultValues.resetData();
return currentValues;
});

Ext js store has Many copy to another store

I have data store "a" with hasMany attribute,trying to create new store "b" by copying hasMany records of "a" with below code,but when i use b store for combo box it throws error saying record.length is undefined
var b = Ext.create("Ext.data.store"{
model:'service'});
Ext.getStore("a").each(function(record,id){
for(var i in record){
b.add(record.raw.subservice);
}
})
It works for me, try this. I hope it helps.
function deepCloneStore (source) {
var target = Ext.create ('Ext.data.Store', {
model: source.model
});
Ext.each (source.getRange (), function (record) {
var newRecordData = Ext.clone (record.copy().data);
var model = new source.model (newRecordData, newRecordData.id);
target.add (model);
});
return target;
}
Original source code reference.
You are trying to iterate store, instead you need to iterate store.data.items.
And you do not need for cycle for record.
Try this
var b = Ext.create("Ext.data.store"{
model:'service'
});
Ext.getStore("a").data.items.each(function(record,id){
//You can add multiple records by calling .add method once
b.add(record.data.subServiceItems);
});
Write if this does not help.

Modifying javascript class attributes

What i am trying to do here is, I have the following class Session
function Session(){
this.accounts = {};
this.setupAccounts = function(res){
this.accounts = res;
log(res);
log(this.accounts);
};
this.test = function(){
log(this.accounts);
};
}
The class Session has an attribute accounts, which will keep store certain data. But in order to initialize it, i initialize it as an empty object.
Next I call the method setupAccounts to modify the value of accounts. For example, I read a file, load it's data and then store that data inside accounts.
But I am having scope problems.
For example the following code :
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(session.setupAccounts);
session.test();
So what i am doing in the code above is fetching the contents of a file as a Json Object and then I am passing that data to the method setupAccounts in order to store that data in the variable accounts. But my output looks like the following:
Object {arjrule3: Object} // printing the json object read from file
Object {arjrule3: Object} // locally changed value of accounts
console.log(session.accounts) // printing global value of accounts
{} // value has not changed.
What am i doing wrong? Why isn't the value for accounts changing for the object session ?
Something Funny just happened, if i write the code as the following:
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(function(res){
session.setupAccounts(res); // Change Here
});
Output:
Object {arjrule3: Object}
Object {arjrule3: Object}
session.accounts
Object {arjrule3: Object} // works! Why ?
It works, why is it so ?
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(session.setupAccounts);
session.test();
In the above example you're just passing the function "setupAccounts" as the callback. You would need to bind it first e.g.
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(session.setupAccounts.bind(session));
session.test();
The other example you've added works because you're calling the "setupAccounts" function on the session object, not just passing a reference to it.

Meteor Storing and Retrieving Custom Objects in Session

I have a custom shopping cart object that I created and put it in the lib folder.
ShoppingCart = function ShoppingCart() {
this.Items = new Array();
this.grandTotal = 0.00;
}
ShoppingCart.prototype.addItem = function(Item){
this.Items.push(Item);
this.Items.sort();
this.calculateTotal();
}
I initialized the shopping cart and store it as Session.set('shoppingCart') during the page created phase.
Template.loginStatus.created = function() {
Session.set('loginShown',false);
if(!Session.get('shoppingCart')){ //set default if session shopping cart not exist
var cart = new ShoppingCart();
Session.setDefault('shoppingCart',cart);
}
Then when user click add item to cart, it will trigger this logic:
var cart = Session.get('shoppingCart');
cart.addItem(item);
Session.set('shoppingCart',cart);
Somehow, it does not work. When I take a look ad the chrome console it says undefined is not a function, pointing at cart.addItem(item) line. If I change it to this, it will work , but of course since everytime new shopping cart is created, I cannot accumulate items in the cart.
var cart = new ShoppingCart();
cart.addItem(item);
Session.set('shoppingCart',cart);
How should I store and retrieve the object from session properly? It looks like the returned object from the Session.get() somehow not considered as ShoppingCart. Did I miss any type cast?
As #Peppe L-G mentioned, you can only store EJSONs in Session. To store your custom object, you need to be able to manually transform it to and from EJSONs. Example:
_.extend(ShoppingCart, {
fromJSON: function(json) {
var obj = new ShoppingCart();
obj.grandTotal = json.grandTotal;
obj.Items = json.Items;
return obj;
},
});
_.extend(ShoppingCart.prototype, {
toJSON: function() {
return {
grandTotal: this.grandTotal,
Items: this.Items,
};
},
});
Then you can save it to Session:
Session.set('shoppingCart', cart.toJSON());
and restore:
ShoppingCart.fromJSON(Session.get('shoppingCart'));
I ran into the same problem. Essentially what is happening Meteor Sessions (and Collections) can only store EJSON types, so your ShoppingCart custom type is retrieved from the Session as a normal Object.
While you can manually transform to and from EJSONs, you may end up needing to do this repeatedly in a lot of different places. If your ShoppingCart is a member of another object, you'll have to also manually transform the member. It's better to use EJSON.addType to tell Meteor how to handle it automatically anywhere you store or retrieve an object of that type.
There's a great demo of this here: https://www.eventedmind.com/feed/meteor-create-a-custom-ejson-type. Full docs are also here: http://docs.meteor.com/#/full/ejson. But a short version is this:
Add a method to your custom type called typeName:
ShoppingCart.prototoype.typeName = function(){
return "ShoppingCart";
};
Add another method called toJSONValue:
ShoppingCart.prototype.toJSONValue = function(){
/* return a JSON compatible version of your object */
};
And finally, add the custom type to EJSON with:
EJSON.addType("ShoppingCart", function fromJSONValue(value){
/* return an object of your custom type from the JSON object 'value' */
};
NOTE: the "Type Name" in steps 1 and 3 must match exactly.

Categories