Sencha touch 2 error, identifier generation strategy for the model does not ensure unique id's, while working with a store - sencha-touch

In Sencha touch, I have defined a store:
Ext.define('TestApp.store.TokenStore', {
extend: 'Ext.data.Store',
config: {
model: 'TestApp.model.TokenModel',
autoLoad: true,
autoSync: true,
proxy: {
type: 'localstorage',
// The store's ID enables us to eference the store by the following ID.
// The unique ID of the Store will be the ID field of the Model.
id: 'TokenStore'
}
}
});
And a model for this store:
Ext.define('TestApp.model.TokenModel', {
extend: 'Ext.data.Model',
config:{
fields: [
{name: 'id', type: 'int' },
{name:'token',type:'string'}
]
}
});
Now, inside the launch function of my App, I do the following:
// Get the store
var tokenStore = Ext.getStore('TokenStore');
// Add a token to the store
tokenStore.add({'token': 1234});
// Retrieve that token back:
var token = tokenStore.getAt(0).get('token');
Everything works, I see the token's value in the console, but I get the following warning:
[WARN][Ext.data.Batch#runOperation] Your identifier generation strategy for the model does not ensure unique id's. Please use the UUID strategy, or implement your own identifier strategy with the flag isUnique.
What am I doing wrong?

Add this inside your config on the model:
identifier: {
type: 'uuid'
},
Sencha Touch requires each record across all classes to have a identifier. Basically, that's a class that assigns a string to each record. There's javascript classes in the touch source that generate these. Those classes must declare themselves either unique or not. uuid is the best to use that's included in sencha touch and declares itself as unique (with good reason if you take a look at the math it does based on timestamps!)
The reason you need unique identifiers is so that records are not mixed up with each other, especially when it comes to DOM interactions or saving/loading them via a proxy.

This will get rid of the warning and subsequent problems loading/saving, which will otherwise crop up after a number of saves/retrieves on the same store (the store will get eventually corrupted)
identifier: {
type: 'uuid',
isUnique : true
},
Tested in Chrome

Related

ExtJS (4.1) creating static data store

I am no JS star so I'm having trouble finding a solution to something that is probably easier than I know.
the page loads, but the ui content stops when it hits the ui code to load the static store data. The preexisting project uses dynamically grabbed data from the database but this just needs a small list of options. (I miss the days of just using HTML). Firebug shows a non-helpful error in ext-all.js that q is undefined, but since that's obfuscated well maintained code I'm sure it's a problem in my code. Do I need to define the proxy for this even if it's static data? Thank you ahead of time!
Here is the model, store, and ui code
//model
Ext.define('HITS.model.ComboBox', {
extend: 'Ext.data.Model',
fields: [
{type: 'string', name: 'label', mapping: 'label'},
{type: 'string', name: 'value', mapping: 'value'}
]
});
//store
Ext.define('HITS.store.ReportType', {
extend: 'Ext.data.Store',
model: 'HITS.model.ComboBox',
storeId:'ReportType',
data: [
{label:'All Tags', value: 'AllTags'},
{label:'Key Findings', value: 'KeyFindings'}
]
});
//ui
<ui:ComboBox
renderTo="ui_report_list"
fieldLabel="Report:"
inputId="reportSelect"
store="ReportType">
The solution had a couple of changes required. The first was the "value" column, which is of course a reserved word in the database(oracle). The other was because I didn't add some prefunction comments for the model that trigger autogenerated code(I hate this practice).
The code here should mostly work but you'd need the model I ended up using. If you check sencha and don't use reserved words you should be ok.

Grouping WSAPI data store by Parent Name

I am creating a rallygrid component and would like to have the grid items grouped by their parent's Name attribute (bonus if I could also display the ID of the parent). I added the groupBy:'Parent' configuration to the storeConfig of the grid and was surprised that no results were returned. I also tried using groupBy:'Parent.Name' but still nothing.
I know this is possible with other fields such as Owner, but I'm at a loss as to why the Parent wouldn't be usable as well. Is this a bug, or am I setting the config up incorrectly?
Thanks
Change the storeConfig to keep the records from trying to update after being grouped:
storeConfig : {
remoteSort : false,
remoteGroup : false,
remoteFilter : false,
}
Add a listener to the load event which assigns a root level property to the record and groups by that record value. (For some reason store.group('Parent.Name'); doesn't work.)
load: function(store) {
store.each(function(record) {
record.set('ParentName', record.get('Parent') && record.get('Parent').Name || '-- Unparented --');
});
store.group('ParentName');
}
I thought it was a bug with the SDK too, but per WS API documentation, Parent, unlike Owner, or Feature is not sortable.
So when I use groupField: 'Parent' the grid is empty, and response showed error:
Ext.data.JsonP.callback6({"QueryResult": {..., "Errors": ["Cannot sort using attribute Parent"]
It is trying to sort by Parent, but Parent attribute is not sortable. So the SDK ran into a WS API limitation.
On a side note, I did not use groupBy, instead I used groupField on the store (in this example I grouped by Kanban field) :
var myStore = Ext.create('Rally.data.WsapiDataStore',{
model: 'UserStory',
groupField: 'c_MyKB',
//...
});
And then used features: [{ftype:'grouping'}] in the grid.
this._myGrid = Ext.create('Ext.grid.Panel', {
store: myStore,
features: [{ftype:'grouping'}],
//...

How to access the elements in a sencha touch 2 store

I am new to Sencha Touch so I am still struggling with the usage of stores.
I have created this store which I am successfully using to populate a list:
Ext.define('EventApp.store.events',{
extend: 'Ext.data.Store',
config: {
model: 'EventApp.model.event',
autoLoad: true,
storeId: 'events',
proxy:{
type:'ajax',
url: './resources/EventData.json',
reader: {
type: 'json',
rootProperty: 'events'
}
}
}
});
As I mentiones this store works correctly when referenced from a list and I can display the contents of it. Therefore I am assuming the store is correctly defined.
Unfortunately when I try to access the store from a controller for one of my views (which will be used to populate the items of a carousel) I don't seem to get any data back from the store. The code I am using is the following:
onEventCarouselInitialize : function(compon, eOptions) {
var past = compon.getPast();
var eventsStore = Ext.getStore('events');
eventsStore.each(function(record){
console.log('Record =',record); //<-- this never gets executed.
},this);
}
I have tried executing an eventsStore.load() on an eventsStore.sync() but I never seem to get any elements available in the store.
What am I missing?
Thanks
Oriol
What i have understand is, perhaps your store data has not been loaded when you are accessing it. So put you each() function on store inside this for delaying 500ms:
Ext.Function.defer(function(){
// Put each() here
}, 500);
Have a try by delaying more or less.

How do you get field properties

I'm working on a Sencha app and having trouble accessing the fields of a basic model that I've defined. I use Ext.define to define a model and Ext.create to create an instance of it. According to the docs I should be able to access its fields by calling get.(<fieldname>) on the field, but it's not working and it's returning null. Here's the basic code, along with a jsfiddle.
Ext.define('App.model.Patient', {
extend: 'Ext.data.Model',
config: {
fields: ['admissionGuid',
'firstName', 'middleInitial', 'lastName', 'visitType',
{ name: "visitDate", type: 'date'}]
}
});​
var newVisit = Ext.create('App.model.Patient', {
admissionGuid: 1234,
firstName: "FirstName",
middleName: "MiddleName",
lastName: "LastName",
visitType: "Revisit",
visitDate: new Date()
});
alert(newVisit.get('admissionGuid')); // returns null
Your code is correct using Sencha Touch 2. I've tested it, and it works as expected. Fiddle here using ST: http://www.senchafiddle.com/#6Q9ac
ExtJS and Sencha Touch share similar class systems, but they are not identical.
The data that you passed gets stored in the raw parameter so try this
alert(newVisit.raw.admissionGuid);
This should work
just an alternative way,
we can also access the data inside model by:
*instanceOfModel*.data.*fieldName*
so for example with the given code it will be:
newVisit.data.admissionGuid

insert in sencha touch data store

Could someone please explain how the insert works to add a record in a datastore
with tha fields: "title", "info" and "price"?
because i tried some things and none of them work. and the sencha website doesnt make it very clear.
Adding a new item to an existing Store isn't that hard actually.
First of you will need to configure your model and store. In your question you name the fields 'title, 'info' and 'price'.
Model:
Ext.regModel('myModel', {
fields: [
{name: 'id', type: 'int' },
{name: 'title', type: 'string' },
{name: 'info', type: 'string' },
{name: 'price', type: 'int' }
]
});
Next you configure the store that will hold the data, based on the above model. I think that, in your case, it should be a model without any data preloaded via, for example, JSON?
So lets make a localstorage (empty store). The Store consists of the model (myModel), you give it a storeID (so that you can later on reference the store by this ID). The proxy is localstorage and the unique ID of the Store will be the ID field of the Model.
Store:
var myStore = new Ext.data.Store({
model: "myModel",
storeId: "myStoreID",
proxy: {
type: "localstorage",
id: "id"
}
});
Now, suppose you have some kind of Form (in which the user can add input a title, info and price, and you want to add these items to the existing store on submittal.
Within the handler of the submittal button you now have to 'call' the store, and perform the add function on it. Within this add function you will have to define the params (the model params) and the data to insert.
Below I have used a mixture of fixed data and a variable to insert.
myStoreID.add({ title: "Mijn Titel", info: "Informatie, price: prijsvar });
The store will now be filled will now be filled with an extra data-record which you can use. Lets say for example that the store is attached to a dataview, then you can perform:
dataView.update();
The above isn't a full tutorial, but I think this will help you along?
Just an update of the YDL answer.
As per the dataView should be related to the updated store, the last sentence dataView.update() should not be needed, due to the automatic update of the views related to a store when it change.
new Ext.DataView({
store: MyStore,
itemSelector: 'div.thumb',
tpl: thumbTpl
});
later, if I do the following, the new item should be displayed in views (List, DataView, etc.) that have MyStore as store.
MyStore.add(newItem);
HTH.
Milton Rodríguez.
If you are trying to pass in an object that was returned from a getValue() on your form, make sure that you run a
myStore.sync();
after you have called the add() method, or you wont see it in your browsers local store.
It is Very easy try these
// first get those values and store in locally
var A_select1=Ext.getCmp('select1').getValue(); // get value
localStorage.setItem("Adult1_select1",A_select1); // set localStore
var AdultSalutation={
'Adult1_select1':A_select1, // assign the value
};
var AdultSalutationstore = Ext.getStore('Adult_AdultSalutationstore'); // get store
AdultSalutationstore.add(AdultSalutation); // add object
AdultSalutationstore.sync(); // sync
AdultSalutationstore.load(); // load