Possible Duplicate: How to set url and root dynamically in extjs
Hi there, I have a simple memoryStore. If I tried not to declare its proxy during the Ext.Define, I am unable to retrieve the proper data root later on, even if I do set the proxy. Am I doing something wrong?
Here's a test case:
var store = Ext.create('Ext.data.Store', {
storeId: 'JailNames',
autoLoad: true,
fields: [
{
name: 'name',
type: 'string'
},
],
data: {
data_regionI: [
{name: "Jail 1"},
{name: "Jail 2"},
{name: "Jail 3"},
],
data_regionII: [
{name: "Jail 4"},
{name: "Jail 5"},
{name: "Jail 6"},
],
},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'data_regionI'
}
}
})
store.setProxy({
type: 'memory',
reader: {
type: 'json',
root: 'data_regionII'
}
} )
store.load();
store.getAt(0).raw //still returns Jail 1
Looking through store.getProxy().reader.root I get the data_regionII as a root. Why?
Thanks in advance
If I copy your code into a sencha fiddle of Version 4.1.1, it throws an Uncaught TypeError: Cannot read property 'raw' of undefined, which is what I expected, because the store shouldn't contain any records at all after the call to load().
There are many problems in your understanding what a store does and what a proxy does:
A normal store's load function will tell the proxy to fetch the data, tell the reader to make records from it, and load it into the data property of your store, overwriting(!) the data you have defined at initialization.
But a memory store's load function isn't intended to do anything at all, and isn't intended to be used at all.
A memory store isn't intended to hold more than one store content at the same time. (you can, however, store the unused contents in an unused(!) property of the store's JavaScript object).
A store, no matter which proxy, does not require autoLoad:true to load the content of data into the store - the content of data is automatically used as the default data of the store after initialization.
That said, it's still possible to achieve what you want with just a few lines of code. You don't even have to create all the functions I only made for readability:
var store = Ext.create('Ext.data.Store', {
storeId: 'JailNames',
fields: [
{
name: 'name',
type: 'string'
},
],
myData: { // custom property!
data_regionI: [
{name: "Jail 1"},
{name: "Jail 2"},
{name: "Jail 3"},
],
data_regionII: [
{name: "Jail 4"},
{name: "Jail 5"},
{name: "Jail 6"},
],
},
loadRegion1:function() {
this.loadRegion("data_regionI");
},
loadRegion2:function() {
this.loadRegion("data_regionII");
},
loadRegion:function(rootProperty) { // custom function for better readability
this.loadRawData(this.myData[rootProperty]); // load data without proxy, but with reader!
},
proxy: {
type: 'memory',
reader: {
type: 'json'
}
}
});
store.loadRegion1();
console.log(store.getAt(0).get("name")); //returns Jail 1
store.loadRegion2();
console.log(store.getAt(0).get("name")); //returns Jail 4
Related
I am having problems loading an array of data from an external file into my store.
This is the file containing the data:
/data/contacts
[
["Lisa", "lisa#hotmail.com", "555-222-3333"],
["Bart", "bart#hotmail.com", "555-222-3333"],
["Homer", "homer#hotmail.com", "555-222-3333"],
["Marge", "marge#hotmail.com", "555-222-3333"]
]
This is my store:
Ext.define('MyApp.store.Contacts', {
extend: 'Ext.data.Store',
autoLoad: true,
alias: 'store.contacts',
model: 'MyApp.model.Contact',
proxy: {
type: 'ajax',
reader: {
type: 'array'
},
url: '../data/contacts'
}
});
This is my model:
Ext.define('MyApp.model.Contact', {
extend: 'Ext.data.Model',
alias: 'model.contact',
fields: [
{name: 'name', mapping: 0},
{name: 'email', mapping: 1},
{name: 'phone', mapping: 2},
]
});
And I am getting this error:
[E] Ext.JSON.decode(): You're trying to decode an invalid JSON String: [
["Lisa", "lisa#hotmail.com", "555-222-3333"],
["Bart", "bart#hotmail.com", "555-222-3333"],
["Homer", "homer#hotmail.com", "555-222-3333"],
["Marge", "marge#hotmail.com", "555-222-3333"]
]
Does anyone have any suggestions on what I am doing wrong, or what I should do? Preferably I do not want to change the format of the array in the data file.
Okay, I realized what I did wrong. It was a very stupid user error made by me.
In my data file: /data/contacts, what I really had was this:
[
["Lisa", "lisa#hotmail.com", "555-222-3333"],
["Bart", "bart#hotmail.com", "555-222-3333"],
["Homer", "homer#hotmail.com", "555-222-3333"],
["Marge", "marge#hotmail.com", "555-222-3333"]
]
// [
// {name: 'Lisa', email: 'lisa#simpsons.com', phone: '555-222-1212'},
// {name: 'Bart', email: 'bart#simpsons.com', phone: '555-333-2212'},
// {name: 'Homer', email: 'homer#simpsons.com', phone: '555-122-1212'},
// {name: 'Marge', email: 'marge#simpsons.com', phone: '555-123-1212'}
// ]
I was previously testing other options for my JSON format, and I was silly enough to think that I could place comment //'s in a normal file.
Removing the comments from the file will fix the error. The array defined in this file can now be loaded into the store.
The error message says that the received JSON is invalid. You can check the validity online at http://jsonlint.com. If it is invalid it is the first thing to fix.
Then, I see the combination of ajax proxy and array reader for the first time in many years with Ext and I'm not sure it is supported.
I am using Sencha Touch 2.3 and Extjs 4.2
Issue: Handle multiple root nodes JSON response(from single response) in multiple stores.
{
total:
[
{
exp_amount_tot: "71962.00",
income_amount_tot: "462129.00"
}
],
data:
[
{
id: "1",
userid: "2",
name: "Any",
notes: "",
},
]
}
I need to save the above response into two different stores.
1. dataStore rootproperty:"data"
2. summaryStore rootProperty: "total"
Please help me to fix this issue.
Store:
proxy: {
type: "ajax",
api: {
create: "http://localhost/api/getAccounts.php/create",
read: "http://localhost/api/getAccounts.php/getall",
update: "http://localhost/api/getAccounts.php/update",
},
reader: {
type: "json",
successProperty: 'success',
rootProperty: 'data',
messageProperty: 'message'
},
},
you can create 2 different stores with "data" & "total" root properties respectively and use the store.add() method to add the data to individual store.
I'm attempting to populate a grid with a data store that uses a proxy and a defined model and reader. Similar stores aren't having the same issue, but one is.
Model
Ext.define('DrillDescriptionGridModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'sentTime', type: 'string'},
{name: 'sDescription', type: 'string'},
{name: 'receivedTime', type: 'string'},
{name: 'seconds', type: 'number'},
{name: 'formatted', type: 'string'},
{name: 'alertPhone', type: 'string'},
{name: 'alertEmail', type: 'string'}
]
});
Reader
var DrillDescriptionReader = Ext.create('Ext.data.JsonReader', {
type: 'json',
model: 'DrillDescriptionGridModel',
root: 'data'
});
Store
DrillDescriptionStore = Ext.create('Ext.data.Store', {
model: 'DrillDescriptionGridModel',
autoLoad: false,
proxy: {
type: 'ajax',
url: '/inc/ajax/Monitors.php',
actionMethods: 'POST',
reader: DrillDescriptionReader
},
listeners: {
load: function() {
console.log(this.getAt(0));
DrillDescriptionPanel.show();
}
}
});
The proxy returns a json string
{"data":[{"sDescription":"Status Normal","sentTime":"12:00:00 am","receivedTime":"12:00:01 am","seconds":"2","formatted":"2 seconds","alertPhone":"","alertEmail":""}, [...]
The console.log in the load listener displays
Ext.Class.c.m
data: Object
alertEmail: ""
alertPhone: ""
formatted: "2 seconds"
receivedTime: "12:00:01 am"
seconds: 2
sentTime: "12:00:00 am"
__proto__: Object
[...]
raw: Object
alertEmail: ""
alertPhone: ""
formatted: "2 seconds"
receivedTime: "12:00:01 am"
sDescription: "Status Normal"
seconds: 2
sentTime: "12:00:00 am"
__proto__: Object
[...]
Anyone know why the sDescription field would be mapped in the raw object, but not the data object, or spot an error in the code? Any help would be greatly appreciated. Thanks.
if you are using extjs 4 as you tagged it .. then the json reader is not defined properly
The class should be Ext.data.reader.Json
So I've figured this one out, and unfortunately it had NOTHING to do with the code that I posted. Thanks for all the help Rocky.
I had another store a little further down in the code that was trying to utilize the same reader... which seems like it shouldn't have been a problem at all, but apparently was. Modified the reader in the store below and code worked right away.
Thanks again for the help Rocky, and thanks for taking a look nscrob.
I asked this question before the weekend and am still stuck despite following the advice. This time I will post all of the relevant code in the hope someone can help me get to the bottom of this.
Important note: the data store and model work perfectly when I statically enter the data into the data store using the data: [{ json data }] parameter of the store. But doing it using ajax proxy fails (even though I can see in chrome that test.php gets called and echoes out the json data (see test.php below).
This is my store:
new Ext.data.Store({
model: "SearchResult",
proxy: {
type: "ajax",
url : "test.php",
extraParams : 'test',
reader: {
type: "json",
}
},
});
I load it when a button is clicked on via a handler.
Here is what is echoed out in test.php:
<?php
echo "[{stock: 'Tommy', storePhone: '353535', year: '1984', make: 'Ferrari', trim: 'trim', miles: '12345', storename: 'branch name' }]";
?>
Been stuck on this for a while so any help much appreciated!
It;s not enough to echo a string that looks like your json ... you should use php methods to encode it ... for your example it will be
<?php
$data = array(array('stock'=> 'Tommy', 'storePhone'=> 353535, 'year'=> '1984', 'make'=> 'Ferrari', 'trim'=> 'trim', 'miles'=> '12345', 'storename'=> 'branch name' ));
echo json_encode($data);
?>
You need to provide a "success: true" property and put your data into a root property in your JSON response.
You should then add the root property to your reader's config.
{
"success": true,
"rows": [
{
"stock": "Tommy",
"storePhone": "353535",
"year": "1984",
"make": "Ferrari",
"trim": "trim",
"miles": "12345",
"storename": "branchname"
}
]
}
Your store:
new Ext.data.Store({
model: "SearchResult",
proxy: {
type: "ajax",
url : "test.php",
extraParams : 'test',
reader: {
type: "json",
root: 'rows'
}
},
});
This solves the issue
store.proxy.url = 'loader.php?user=' + var_here;
store.load();
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);
});
}
}
});