Ext js store has Many copy to another store - javascript

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.

Related

Firebase realtime database + JS object

I have a really simple JS code:
var worldRef = firebase.database().ref('something/something1');
var something = new Object();
worldRef.on('child_added', function(snap) {
something.id = snap.key;
something.value = snap.val().value;
});
console.log(something);
It works almost fine - just one key&value from database, but it's something. If I modify it:
console.log(something.id);
Undefined. I've tried with map instead of object, but same. I see everything in map, but when I try to call the getmap(key), it's undefined.
Array-based solution:
var worldRef = firebase.database().ref('something/something1');
var something = [];
worldRef.on('child_added', function(snap) {
something.push ({
id: snap.key,
value: snap.val().value
})
});
console.log(something);
It works.
This is because each time a child is added, you re-assign the id and value properties of your something object.
Since, the child_added event is triggered once for each initial child at this location (see the doc), at the end your object just contains the last children element.
If you do as follows (creating a new property for each child), you will see the same effect than with the Array:
var something = new Object();
worldRef.on('child_added', function (snap) {
something[snap.key] = snap.val().value;
});

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;
});

How to make checkboxes work with knockout

I found this example from Ryan Niemeyer and started to manipulate it into the way I write my own code, but then it stopped working. Can anybody tell me why?
Alternative 1 is my variant
Alternative 2 is based upon Ryans solution and does work (just comment/uncomment the Applybindings).
Why doesn´t Alternative 1 work?
My issue is with the filteredRows:
self.filteredRows = ko.dependentObservable(function() {
//build a quick index from the flags array to avoid looping for each item
var statusIndex = {};
ko.utils.arrayForEach(this.flags(), function(flag) {
statusIndex[flag] = true;
});
//return a filtered list
var result = ko.utils.arrayFilter(this.Textbatches(), function(text) {
//check for a matching genré
return ko.utils.arrayFirst(text.genre(), function(genre) {
return statusIndex[genre];
});
return false;
});
console.log("result", result);
return result;
});
I want to filter my Textbatches on the genre-attribute (string in db and the data collected from the db is a string and not an array/object)
Fiddle here: http://jsfiddle.net/gsey786h/6/
You have various problems, most of them can be simply fixed with checking your browser's JavaScript console and reading the exceptions...
So here is the list what you need to fix:
You have miss-typed Textbatches in the declaration so the correct is self.Textbatches = ko.observableArray();
You have scoping problem in filteredRows with the this. So if you are using self you should stick to it and use that:
this.flags() should be self.flags()
this.Textbatches() should be self.Textbatches()
Your genre property has to be an array if you want to use it in ko.utils.arrayFirst
Finally your Textbatch takes individual parameters but you are calling it with an object, so you need to change it to look like:
Textbatch = function(data) {
var self = this;
self.id = ko.observable(data.id);
self.name = ko.observable(data.name);
self.statuses = ko.observableArray(data.status);
self.genre = ko.observableArray(data.genre);
self.createdBy = ko.observable(data.createdBy);
};
or you can of course change the calling places to use individual arguments instead of an object.
Here is a working JSFiddle containing all the above mentioned fixes.

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