Data model : Association getter returns undefined - extjs

My problem consists of not being able to retrieve data through associations.
After running setup() from console i would expect firstTurbine.getPlant() to return the associated plant, yet it returns undefined.
I've spent alot of time looking for a solution I'm probably not looking the right place.
Relevant code is attached below:
Ext.regApplication({
name: "app",
launch: function() {
//app.views.viewport = new app.views.Viewport();
}
});
app.models.Plant = Ext.regModel("Plant", {
fields: [
{name: "id", type: "int"},
{name: "name", type: "string"},
{name: "notes", type: "auto"}
],
proxy: {type: 'localstorage', id:'plantStorage'}
});
app.models.Turbine = Ext.regModel("Turbine", {
fields: [
{name: "id", type: "int"},
{name: "plant_id", type: "int"},
{name: "name", type: "string"},
{name: "notes", type: "auto"}
],
proxy: {type: 'localstorage', id:'turbineStorage'},
belongsTo: 'Plant'
});
app.stores.plants = new Ext.data.Store({
model: "Plant",
autoLoad: true,
data : [
{id: 1, name: 'Plant1', notes: ["Note1", "Note2"]},
{id: 2, name: 'Plant2', notes: ["Note1", "Note2"]},
{id: 3, name: 'Plant3', notes: ["Note1", "Note2"]}
]
});
app.stores.turbines = new Ext.data.Store({
model: "Turbine",
autoLoad: true,
data: [
{id: 11, "plant_id": 1, name: "T41", notes: ["Turbine note 1", "Turbine note 2"]},
{id: 12, "plant_id": 1, name: "T13", notes: ["Turbine note 1", "Turbine note 2"]}
]
});
function setup(){
firstPlant = app.stores.plants.getAt(0);
if(!firstPlant){
firstPlant = Ext.ModelMgr.create({name:"TestPlant1", id: 1}, "Plant");
app.stores.plants.add(firstPlant);
app.stores.plants.sync();
}
firstTurbine = app.stores.turbines.getAt(0);
if(!firstTurbine){
firstTurbine = Ext.ModelMgr.create({name:"T31", id: 30, plant_id: 1}, "Turbine");
app.stores.turbines.add(firstTurbine);
app.stores.turbines.sync();
}
return {firstTurbine: firstTurbine, firstPlant: firstPlant};
}

The getter function created by the belongsTo association takes a callback function as argument. The callback function will have the related object as its first argument.
turbine.getPlant(function(Plant){
console.log(Plant);
});
I will attach a full working example since this have cost me alot of headache and might have aswell for others.
first the json data:
{
"plants": [{
"id": 1,
"name": "Plant1",
"notes": ["Note1", "Note2"]
}],
"turbines": [
{
"id": 11,
"plant_id": 1,
"name": "T41",
"notes": ["Turbine note 1", "Turbine note 2"]
}]
}
And the javascript:
Ext.regApplication({
name: "app",
launch: function() {}
});
app.models.Plant = Ext.regModel("Plant", {
fields: ["id", "name", "notes"],
proxy: {
type: 'ajax',
url: 'data.json',
reader: {
type: 'json',
root: 'plants'
}
}
});
app.models.Turbine = Ext.regModel("Turbine", {
fields: ["id", "plant_id", "name", "notes"],
proxy: {
type: 'ajax',
url: 'data.json',
reader: {
type: 'json',
root: 'turbines'
}
},
belongsTo: 'Plant'
});
app.stores.plants = new Ext.data.Store({
model: "Plant"
});
app.stores.turbines = new Ext.data.Store({
model: "Turbine",
autoLoad: {
callback: function(records) {
var turbine = records[0];
turbine.getPlant(function(Plant){
console.log(Plant);
});
}
}
});

Related

creating nested structure with backbone-relational

I'm trying to create a three cascading dropdown lists. First one constains projects, second contains tasks for selected project and the last one sites for selected task.
I want to use the Backbone-Relational plugin, but have hard time to create the proper relations. That's my first time with this plugin.
Code so far:
App.Models.ProjectItem = Backbone.RelationalModel.extend({
default: {
id: 0,
name: ''
},
relations: [{
type: Backbone.HasMany,
key: 'tasks',
relatedModel: App.Models.TaskItem,
//includeInJSON: Backbone.Model.prototype.idAttribute,
collectionType: App.Collections.TasksCollection,
reverseRelation: {
key: 'projectId',
//includeInJSON: Backbone.Model.prototype.idAttribute,
type: Backbone.HasOne
}
}]
});
App.Collections.ProjectsCollection = Backbone.Collection.extend({
model: App.Models.ProjectItem
});
App.Models.TaskItem = Backbone.RelationalModel.extend({
default: {
id: 0,
name: ''
},
relations: [{
type: Backbone.HasMany,
key: 'sites',
relatedModel: App.Models.SiteItem,
includeInJSON: Backbone.Model.prototype.idAttribute,
collectionType: App.Collections.SitesCollection,
reverseRelation: {
key: 'taskId',
//includeInJSON: Backbone.Model.prototype.idAttribute,
type: Backbone.HasOne
}
}]
});
App.Collections.TasksCollection = Backbone.Collection.extend({
model: App.Models.TaskItem
});
App.Models.SiteItem = Backbone.RelationalModel.extend({
default: {
id: 0,
name: ''
}
});
App.Collections.SitesCollection = Backbone.Collection.extend({
model: App.Models.SiteItem
});
Creating single project:
var item = new App.Models.ProjectItem({
id: 1,
name: 'project',
tasks: [
{
id: 1,
name: 'task',
sites: [
{
id: 1,
name: 'site'
}
]
}
]
})
This object serialized to json looks like this:
"{"id":1,"name":"task","tasks":[1],"sites":[{"id":1,"name":"site"}],"projectId":null}"
My questions:
1) Why the sites array is not nested in the tasks one?
2) Sites collection is not serialized the same way that tasks one is. Should I create a relations in the site model too?
3) Why the projectId is returned for the root?
After many hours of trials and errors I finally got it. The order matters..
Working code:
App.Models.SiteItem = Backbone.RelationalModel.extend({
default: {
siteId: 0,
name: ''
}
});
App.Collections.SitesCollection = Backbone.Collection.extend({
model: App.Models.SiteItem
});
App.Models.TaskItem = Backbone.RelationalModel.extend({
default: {
taskId: 0,
name: ''
},
relations: [{
type: Backbone.HasMany,
key: 'sites',
relatedModel: App.Models.SiteItem,
//includeInJSON: Backbone.Model.prototype.idAttribute,
collectionType: App.Collections.SitesCollection,
reverseRelation: {
key: 'task',
includeInJSON: 'taskId',
type: Backbone.HasOne
}
}]
});
App.Collections.TasksCollection = Backbone.Collection.extend({
model: App.Models.TaskItem
});
App.Models.ProjectItem = Backbone.RelationalModel.extend({
default: {
projectId: 0,
name: ''
},
relations: [{
type: Backbone.HasMany,
key: 'tasks',
relatedModel: App.Models.TaskItem,
// includeInJSON: 'taskId',
collectionType: App.Collections.TasksCollection,
reverseRelation: {
key: 'project',
includeInJSON: 'projectId',
type: Backbone.HasOne
}
}]
});
App.Collections.ProjectsCollection = Backbone.Collection.extend({
model: App.Models.ProjectItem
});
For sample data:
var item = new App.Models.ProjectItem({
projectId: 2,
name: 'first',
tasks: [
{
taskId: 1,
name: 'task',
sites:[{siteId:1, name: 'site'}]
}
]
});
I got this json string:
"{"projectId":2,"name":"first","tasks":[{"taskId":1,"name":"task","sites":[{"siteId":1,"name":"site","task":1}],"project":2}]}"

Displaying jsGrid nested object array

Using jsGrid I am attempting to display information from my server. The format that I receive the data is thus:
{
"Response": [
{
"this": "1",
"that": 42,
"theOtherThing": "2016-01-28T19:45:19.093Z"
},
{
"this": "2",
"that": 49,
"theOtherThing": "2016-01-28T19:45:19.093Z"
}
]
}
How can I pull this information out of the object Response so that I can display it in my jsGrid fields?
fields: [
{name: 'this', type: 'text', width: 100},
{name: 'that', type: 'number', width: 100},
{name: 'theOtherThing', type: 'text', width: 100}
]
So I just needed to alter the format of my ajax call:
controller: {
loadData: function () {
var deferred = $.Deferred();
$.ajax({
type: 'GET',
url: 'ThisGoesSomewhere',
dataType: 'json',
success: function(res){
deferred.resolve(res.Response);
},
error: function(res){
console.log('error ' + res);
}
});
return deferred.promise();
}
}

Sencha touch 2.4.1 - localstorage using own ID

I am trying to save data to local storage and I want to use my own ID.
But new id is generated.. and not using my ID.
My model:
Ext.define('mOQOLD.model.ActivityList',{
extend:'Ext.data.Model',
config:{
dProperty : 'uniqueid', // dummy name(not a field)
clientIdProperty : 'ID',
identifier: {
type: 'simple'
},
fields: [
{ name: "ID", type: "auto" },
{ name: "activityID", type: "int" },
{ name: "newRandom", type: "float" },
{ name: "rTime", type: "date", dateFormat: "Y-m-d H:i:s" }
]
}
});
My store:
Ext.define('mOQOLD.store.ActivityListStoreOffline',{
extend:'Ext.data.Store',
requires:["mOQOLD.model.ActivityList",
'Ext.data.proxy.LocalStorage'],
config:{
storeId:"ActivityListStoreOffline",
model:"mOQOLD.model.ActivityList",
grouper: {
groupFn: function(rec) {
var date = rec.get("actDtlStime");
return Ext.Date.format(date, "h a");
}
},
autoLoad:false,
sorters: [
{ property: "actDtlStime", direction: "ASC" }
],
proxy : {
type : 'localstorage',
id : "ActivityListStoreOffline",
model : "mOQOLD.model.ActivityList",
reader: {
type: "json"
}
}
}
})
The result( chrome) :
key : ActivityListStoreOffline-ext-record-19
value:
{"ID":"153",15:13:00","activityID":111,"newRandom":null,"rTime":"2015-05-26 19:31:51","id":"ext-record-19"}
What I expect:
key : ActivityListStoreOffline-153
value:
{"ID":"153",15:13:00","activityID":111,"newRandom":null,"rTime":"2015-05-26 19:31:51"} no id generated!!!
Thanks in advance..
There are two places you can set the ID:
In the model(http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.data.Model-cfg-idProperty)
and in the reader (http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.data.reader.Reader-cfg-idProperty)
Both places use the "idProperty" attribute. Which defaults to lowercase 'id'.
For example, change your reader to:
proxy : {
type : 'localstorage',
id : "ActivityListStoreOffline",
model : "mOQOLD.model.ActivityList",
reader: {
type: "json",
idProperty: "ID",
}
}

Loading nested GeoJson to FeatureStore with hasMany. Possible?

Is it possible to use associations while loading nested GeoJson to FeatureStore via vectorLayer?
Ext.define('Employee', {
extend: 'Ext.data.Model',
proxy: {
type: 'memory',
reader: {
type: 'json',
idProperty: 'id'
}
},
fields: [ { name: 'name', type: 'string' } ]
});
Ext.define('Company', {
extend: 'Ext.data.Model',
proxy: {
type: 'memory',
reader: {
type: 'json',
idProperty: 'id'
}
},
fields: [ { name: 'name', type: 'string' } ],
hasMany: { model: 'Employee', name: 'employees' }
});
var jsonData = {
companies: [
{
name: 'Foo',
employees: [
{ name: 'Jack' },
{ name: 'Joe' }
]
},
{
name: 'Bar',
employees: [
{ name: 'Jim' }
]
}
]
};
Ext.define('CompaniesExt', {
extend: 'Ext.data.Store',
model: 'Company',
data: jsonData,
storeId: 'CompaniesExt',
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'companies'
}
}
});
Ext.define('CompaniesGeoExt', {
extend: 'GeoExt.data.FeatureStore',
model: 'Company',
storeId: 'CompaniesGeoExt'
});
// data from json
var jsonStore = Ext.create('CompaniesExt');
// data from geoJson
var map = new OpenLayers.Map({ allOverlays: true });
var geoJsonStore = Ext.create('CompaniesGeoExt');
var layer = new OpenLayers.Layer.Vector('Companies', {
storeName: 'CompaniesGeoExt',
strategies: [
new OpenLayers.Strategy.Fixed(),
],
protocol: new OpenLayers.Protocol.HTTP({
url: "/companies.geojson",
format: new OpenLayers.Format.GeoJSON(),
})
});
map.addLayers([layer]);
geoJsonStore.bind(layer);
So, the first jsonStore works as expected, the employeesStore gets populated for each company. The second geoJsonStore does not. Employees data remain in raw.data and the sub-stores don't ge populated on load.
Is it supposed to work this way, or am I missing something?
Here's the contents of companies.geojson:
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "point",
"coordinates": [ 0, 0 ]
},
"type": "feature",
"properties": {
"name": "Foo",
"employees": [
{ "name": "Jack" },
{ "name": "Joe" }
]
}
},
{
"geometry": {
"type": "point",
"coordinates": [ 1, 1 ]
},
"type": "feature",
"properties": {
"name": "Bar",
"employees": [
{ "name": "Jim" }
]
}
}
]
}
It seems, that the easiest way is to rewrite data after loading features, for example on "featuresadded" event:
rewriteEmployees: function(event){
// which store
var store = event.features[0].layer.store;
// for each item do the rewrite
store.each(
function(r){
if (r.raw.data.emplyees)
r.raw.data.employees.forEach(function(e){
r.employees().add(e);
});
r.employees().commitChanges();
}
);
},

How to customise extjs remote extensible calendar example with MVC application?

I have downloaded 'extensible-1.6.0-b1', I'm trying to understand the remote example to customise it with my application. I'm coding with extjs 4.0.7.
I want to know how to intgrate the example in mvc application? Is there an example with clear architecture: store+model+controller?
Edit:
This is the code I'm using now:
Ext.define('Webdesktop.view.calendar.Calendar', {
extend : 'Ext.tab.Panel',
alias : 'widget.calendar_calendar',
//autoShow : true,
paths: {
'Extensible': 'extensible-1.6.0-b1/src',
'Extensible.example': 'extensible-1.6.0-b1/examples'
},
requires:([
'Ext.Viewport',
'Ext.layout.container.Border',
'Ext.data.proxy.Rest',
'Extensible.calendar.data.MemoryCalendarStore',
'Extensible.calendar.data.EventStore',
'Extensible.calendar.CalendarPanel'
]),
initComponent: function() {
var me = this;
var calendarStore = Ext.create('Extensible.calendar.data.MemoryCalendarStore', {
autoLoad: true,
proxy: {
type: 'ajax',
url: 'app/data/calendars.json',
noCache: false,
reader: {
type: 'json',
root: 'calendars'
}
}
});
var eventStore = new Ext.data.JsonStore({
autoLoad: true,
fields: [
{name: 'EventId', mapping:'id', type:'int'},
{name: 'CalendarId', mapping: 'cid', type: 'int'},
{name: 'Title', mapping: 'title'},
{name: 'StartDate', mapping: 'start', type: 'date', dateFormat: 'c'},
{name: 'EndDate', mapping: 'end', type: 'date', dateFormat: 'c'}
],
proxy : {
type : 'ajax',
api : {
read : GLOBAL_USER_PROFILE.apiUrl + '_module/calendar/_action/loadEvent'
},
extraParams : {
_module : 'calendar',
_action : 'loadEvent',
_db : '2d3964b9...e53a82'
},
reader : {
type : 'json',
root : 'evts'
},
writer : {
type : 'json',
encode : true
}
},
listeners: {
'write': function(store, operation){
var title = Ext.value(operation.records[0].data[Extensible.calendar.data.EventMappings.Title.name], '(No title)');
switch(operation.action){
case 'create':
Extensible.example.msg('Add', 'Added "' + title + '"');
break;
case 'update':
Extensible.example.msg('Update', 'Updated "' + title + '"');
break;
case 'destroy':
Extensible.example.msg('Delete', 'Deleted "' + title + '"');
break;
}
}
}
});
var cp = Ext.create('Extensible.calendar.CalendarPanel', {
id: 'calendar-remote',
region: 'center',
eventStore: eventStore,
calendarStore: calendarStore,
title: 'Remote Calendar'
});
Ext.apply(me, {
items : {
xtype : 'panel',
activeItem : 0,
layout: {
type: 'fit'
},
border : false, //FIXME: see class comment, bug
defaults : {
closable : false, //FIXME: see class comment, bug
border : false //FIXME: see class comment, bug
},
title : 'الاستقبال',
closable : true,
bodyPadding : 0,
items: [
cp
]
}
});
me.callParent();
}
});
The json returned:
{
"evts":[{
"EventId":"1",
"CalendarId":"0",
"Title":"$data",
"StartDate":"Mon May 13 2013 09:21:57 GMT+0100",
"EndDate":"Mon May 13 2013 09:21:57 GMT+0100",
"Duration":"0",
"Location":"",
"Notes":"",
"Url":"",
"IsAllDay":"0",
"Reminder":""
},{
"EventId":"2",
"CalendarId":"0",
"Title":"$data",
"StartDate":"Mon May 13 2013 09:21:57 GMT+0100",
"EndDate":"Mon May 13 2013 09:21:57 GMT+0100",
"Duration":"0",
"Location":"",
"Notes":"",
"Url":"",
"IsAllDay":"0",
"Reminder":""
}]
}
But events are not displayed in the calendar, and I have this error in Firebug:
TypeError: data[M.StartDate.name] is null
I had the same problem i just solved it yesterday, it's about the format of your date that's incorrect take this may that help you :
so this is my view :
Ext.define('Congectis.view.CalendarTry', {
extend: 'Ext.panel.Panel',
alias: 'widget.calendartry',
requires: [
'Ext.data.proxy.Rest',
'Extensible.calendar.data.MemoryCalendarStore',
'Extensible.calendar.CalendarPanel',
'Extensible.calendar.data.EventStore'
],
autoShow: true,
layout: 'fit',
Store: ['Evts'],
initComponent: function () {
var calendarStore = Ext.create('Extensible.calendar.data.MemoryCalendarStore', {
autoLoad: true,
proxy: {
type: 'ajax',
url: '../../../../../MVC/eLeave/data/event2.json',
noCache: false,
reader: {
type: 'json',
root: 'calendars'
}
}
});
var eventstore = Ext.create('Extensible.calendar.data.EventStore', {
autoLoad: true,
fields: [
{name: 'EventId', mapping: 'EventId', type: 'int'},
{name: 'CalendarId', mapping: 'CalendarId', type: 'int'},
{name: 'Title', mapping: 'Title'},
{name: 'StartDate', mapping: 'StartDate', type: 'date', dateFormat: 'm-d-Y'},
{name: 'EndDate', mapping: 'EndDate', type: 'date', dateFormat: 'm-d-Y'}
],
proxy: {
type: 'ajax',
url: '../../../../../MVC/eLeave/data/event1.json',
noCache: false,
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
nameProperty: 'mapping'
},
listeners: {
exception: function (proxy, response, operation, options) {
var msg = response.message ? response.message : Ext.decode(response.responseText).message;
Ext.Msg.alert('Server Error', msg);
}
}
},
//option for generically messaging after CRUD persistence has succeeded.
listeners: {
'write': function (store, operation) {
var title = Ext.value(operation.records[0].data[Extensible.calendar.data.EventMappings.Title.name], '(No title)');
switch (operation.action) {
case 'create':
Extensible.example.msg('Add', 'Added "' + title + '"');
break;
case'update':
Extensible.example.msg('Update', 'Updated "' + title + '"');
break;
case'destroy':
Extensible.example.msg('Delete', 'Deleted "' + title + '"');
break;
}
}
}
});
this.items = [{
xtype: 'extensible.calendarpanel',
eventStore: eventstore,
calendarStore: calendarStore,
title: 'Calendrier des conges',
name: 'eLeave-calendar',
height: 500,
width: 500
}];
//Extensible.calendar.data.CalendarModel.reconfigure();
this.callParent(arguments);
}
});
This is my json store
{
"success": true,
"message": "Loaded data",
"data": [{
"id": 1001,
"cid": 1,
"start": "2015-03-18T10:00:00-07:00",
"end": "2015-03-28T15:00:00-07:00",
"title": "Vacation",
"notes": "Have fun"
}, {
"id": 1002,
"cid": 2,
"start": "2015-04-07T11:30:00-07:00",
"end": "2015-04-07T13:00:00-07:00",
"title": "Lunch with Matt",
"loc": "Chuy's",
"url": "http:\/\/chuys.com",
"notes": "Order the queso"
}, {
"id": 1003,
"cid": 3,
"start": "2015-04-07T15:00:00-07:00",
"end": "2015-04-07T15:00:00-07:00",
"title": "Project due"
}, {
"id": 1004,
"cid": 1,
"start": "2015-04-07T00:00:00-07:00",
"end": "2015-04-07T00:00:00-07:00",
"title": "Sarah's birthday",
"ad": true,
"notes": "Need to get a gift"
}, {
"id": 1005,
"cid": 2,
"start": "2015-03-26T00:00:00-07:00",
"end": "2015-04-16T23:59:59-07:00",
"title": "A long one...",
"ad": true
}, {
"id": 1006,
"cid": 3,
"start": "2015-04-12T00:00:00-07:00",
"end": "2015-04-13T23:59:59-07:00",
"title": "School holiday"
}, {
"id": 1007,
"cid": 1,
"start": "2015-04-07T09:00:00-07:00",
"end": "2015-04-07T09:30:00-07:00",
"title": "Haircut",
"notes": "Get cash on the way",
"rem": 60
}, {
"id": 1008,
"cid": 3,
"start": "2015-03-08T00:00:00-08:00",
"end": "2015-03-10T00:00:00-07:00",
"title": "An old event",
"ad": true
}, {
"id": 1009,
"cid": 2,
"start": "2015-04-05T13:00:00-07:00",
"end": "2015-04-05T18:00:00-07:00",
"title": "Board meeting",
"loc": "ABC Inc.",
"rem": 60
}, {
"id": 1010,
"cid": 3,
"start": "2015-04-05T00:00:00-07:00",
"end": "2015-04-09T23:59:59-07:00",
"title": "Jenny's final exams",
"ad": true
}, {
"id": 1011,
"cid": 1,
"start": "2015-04-09T19:00:00-07:00",
"end": "2015-04-09T23:00:00-07:00",
"title": "Movie night",
"note": "Don't forget the tickets!",
"rem": 60
}]
}
The problem was with your date format, wish that helped you, good luck
`

Resources