ExtJS 5 load existing store with local data - extjs

I am doing unit testing and would like to add dummy data to an existing store. In the function I am testing, I am calling a store:
var tripStore = Ext.getStore('Trips');
Normally, this store would have been populated by an Ajax call at a previous point. However, since I am testing I want to use dummy data and not rely on the back end. I realize I could rewrite the function to pass in the store, but I do not want to rewrite this for the sake of testing.
Bottom line, how do I add local data to a store that already exists but has no data in it? Furthermore, the back end is not available, so when I try store.load or store.reload it throws a 404 saying it cannot find the url rest/trip. I don't want it to try and call this url, but instead I want to add local data.
The model definition:
Ext.define('app.model.Trip', {
fields:[
{name: 'someField1', type: 'string'},
{name: 'someField2', type: 'string'},
{name: 'someField3', type: 'string'},
],
proxy: {
noCache: true,
url: 'rest/trip',
reader: {
type: 'json',
rootProperty: 'trips'
}
}
});
The (attempted) test script that is calling the url when I don't want it to, but only want it to add the local data:
var tripsStore = Ext.StoreManager.lookup('Trips');
tripsStore.load({
autoLoad: false,
addRecords: true,
proxy: {
data: localData,
},
callback: function(records, operation, success) {
if (success) {
debugger
} else {
debugger
}
}
})

Use ajax.SimManager. See example (open Details on the right-hand side, click on any of the Data tabs).

Related

ExtJs (6.0.0) rest service PUT request

I am trying to PUT some data from my frontend (ExtJs) into my backend (Java, Spring). It does not work or I do not get the right clue...
I am on a Ext.grid.Panel where I use the following store which is (nicely) filled and displayed by a this.store.setData( myObject.data.items ) method:
Ext.define( 'NameOfThisClass', {
extend: 'Ext.grid.Panel',
...
store: Ext.create( 'Ext.data.Store', {
data: [],
autoLoad: false,
proxy: {
type: 'rest',
url: '/somepath/theclass',
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'totalCount'
},
writer: {
type: 'json'
},
}
} ),
...
// setting the data to be visualized
setValue: function(myObject) {
this.store.setData( myObject.data.items );
}
...
updateRecord: function(objectId, objectWithUpdateProperties) {
// do what with the store and/or proxy?
}
...
});
I display all entries in a table. The entries are not automatically loaded by the store but set from outside: setValue(myObject).
There is another store for initially loading the data. The data received is then splittet and forwarded in order not to have several requests.
I do get a nice visualized table whose entries are editable by the rowediting plugin.
Ok, so far the backgrounds.
When editing the table's data I run through some validations and gather more data via a modal dialog and then I have the data in order to send to the server by a call of updateRecord(objectId, objectWithUpdateProperties).
This sending is my problem. I do not know how to call/send a rest/put request which will be read by the server. (Receiving is not the problem, sending is).
I guess I somewhat need to trigger my store or the store's proxy. But how?
It is not that I can simply tell my object to save since I do have more data than just the changed object's properties.
Can anyone help me here?
I normally use Ext.Ajax to achieve that, like this:
updateRecord: function(objectId, objectWithUpdateProperties) {
Ext.Ajax.request({
url: 'YourUrl',
params: {
some_param: 'some_value',
object_id: objectId,
object_with_properties_param1: objectWithUpdateProperties.param1
},
success: function(response, opts) {
//Horay, Do something with the response
},
failure: function(response, opts) {
//Oh nooooo
}
});
}
Don't need to use Ajax.
You need to config proxy.api CRUD(C:create, R:read, U:Update. D:Delete) on RestProxy, from client side.
Also, store must have autoSync:true.
At server side, need to config a #RestController for each one of CRUD (with JSON-Java encoder for parameters like Jackson or equivalent), that will acept JSON data. Take into account, that you may send only modified field (store.proxy.writer.writeAllFields: false ->>> default) or just the full record (.writeAllFields:true) to server.
Here an example (inside store's constructor):
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
autoSync: true,
model: 'Test.model.Country',
proxy: {
type: 'rest',
api: {
create: 'country/create',
read: 'counrtry/list'
update: 'counrtry/update',
destroy: 'counrtry/destroy'
},
writer:{
writeAllFields : true
},
reader:{
root:'items',
totalProperty: 'rowCount'
}
}
}, cfg)]);
}
Extra note: For reading from server and load store automatically, just set store.autoLoad: true, and the corresponding #RestController method from server side. Take into account the store.reader params.

Making a good pagination for a grid - extJS

I'm new to ExtJS.
I followed a tutorial with the aim to create a pagination on a grid.
The code was simple, and I found it suspicious...
as result, the paging toolbar is there but there are still all the data displayed on the first load.
Here's my code in the View file :
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.GridPanel',
alias: 'widget.userlist',
cls: 'overall',
title: 'xxx <img src="ressource/image/xxx.png" class="title-icon" style= "width: 5%; height: 5%; vertical-align:middle; margin-bottom:0px;" />',
columnLines: true,
dockedItems: [{
xtype: 'pagingtoolbar',
store: 'Users',
pageSize: 2,
dock: 'bottom',
displayInfo: true
}],
I also saw tutorial with a var, but I dont' know where to implement it.
I'm sorry I know there is many tutorials about it out of there but I'm struggling on it :(, I don't mastery JS enough !
Thanks by advance ^_^
edit :
My code in my Store file :
var itemsPerPage = 2;
var store = Ext.define('AM.store.Users', {
pageSize: itemsPerPage,
extend: 'Ext.data.Store',
model: 'AM.model.User',
proxy: {
type: 'ajax',
api: {
read: 'application/data/users.json',
update: 'application/data/updateUsers.json',
},
reader: {
type: 'json',
root: 'users',
idProperty: 'POC',
successProperty: 'success',
totalProperty : 'total'
}
},
autoLoad: false,
});
store.load({
params:{
start:0,
limit: itemsPerPage
}
});
This is telling me : Uncaught TypeError: Object function constructor() { ... has no method 'load'
I tried to remove the store.load, and add {start: 0, limit: 2} after the AutoLoad, according with this http://www.objis.com/formationextjs/lib/extjs-4.0.0/docs/api/Ext.toolbar.Paging.html
With this method, the toolbar shows me " 2-13 data displayed " as it should but there is not data displayed in the grid :'(.
Your server-side stack (PHP, .NET, whatever) will need to be aware of the page, start, and limit parameters that are passed through as part of the request. This is what you'll use to create the proper SQL query (or whatever is being done to retrieve the records) to limit the results to match the paging accommodated by the store.
I'm guessing you're getting all the results because your app server is sending back all the results. The paging provided by ExtJS is really just a handshake with whatever code is running on the server...the paging in a remote store isn't limiting the records, your server-side code is. The AJAX request that the store's proxy sends merely tells the server what it expects to receive back as data.
This is telling me : Uncaught TypeError: Object function constructor()
{ ... has no method 'load'
The reason it is telling you this is because you are trying to invoke the load() method on the 'class' instead of on an instance:
var store = Ext.define('AM.store.Users', {
Ext.define defines a class. To get an instance, you should call Ext.create:
var store = Ext.create('AM.store.Users', { /* ... */ });
This should happen after the 'class' has been defined, but before you invoke the load.
Maybe you should make it a habit to store the result of Ext.define in a variable with a name starting with an uppercase letter, so you can see it represents a class and not an instance:
var Users = Ext.define('AM.store.Users', {
Pagination in a grid requires a buffered store. Something like this
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
// snip
buffered: true,
pageSize: 5
// snip
proxy: {
type: 'ajax',
api: {
read: 'application/data/users.json',
update: 'application/data/updateUsers.json',
},
reader: {
type: 'json',
root: 'users',
idProperty: 'POC',
successProperty: 'success',
totalProperty: 'yourTotalProperty'
}
}
});
Check the outgoing requests (chrome developer tools, firebug or fiddler). If they add page info (page and pageSize) to the Users-requests then your Ext Js code is correct. And of course you also need a web service that supports paging and delivers the requested data chunks.

Model without a Store

I created a model which contains a proxy to load a single record and its takes no params. I don't want to use a store since I'll never have more then one record. I create an instance of the Model but can't figure out how to tell it to call and load the record from the server. This is the only example I could find, but I don't have an id to pass.
User.load(123, {
success: function(user) {
console.log("Loaded user 123: " + user.get('name'));
}
});
Also I'm making and ajax call and not a rest call in case that matters.
The load(id, [config]) is static and will return provide you with a new record instance. It uses the proxy that was set via setProxy(proxy) (also static). Per default it will send a read request with the params id: 123. The static method allows you to set some default callbacks within the optional config object. These callbacks are needed to get the instance of the loaded record (or the error).
How it works
// create a Model class
Ext.define('MyApp.User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
]
});
// apply a proxy instance
MyApp.User.setProxy(/*YourAjaxProxy*/);
// prepare a handler
var cb = function(model, op) {
// log the new model instance
console.log(model);
};
// get a instance
MyApp.User.load(123, {
scope: this, // should be the scope of the callback (cb)
success: cb
});
Not what you need? Just comment...
Just make an Ajax request and store the result in a variable.
Ext.Ajax.request({
url: '/data/get',
method: 'GET',
params: {
requestID: 'XXXX',
connName: 'yyyy'
},
success: function (responseData) {
var countResult = Ext.decode(responseData.responseText); }
});

JSONP not working on ExtJS 4 - Uncaught TypeError: Cannot call method 'substring' of undefined

I'm stuck with this code, I'm getting this json formated data from the Youtube API, if I use type:'json' it will fail, because of that cross domain thing but the other elements loads anyway; then, if I change type: to 'jsonp' (which is the syntax described on the ExtJS API) it would give me this error:"Uncaught TypeError: Cannot call method 'substring' of undefined" I tried setting type:'anyotherstupidthing' and the same happens, so what could be happening?
Here are my current data model and my store:
Ext.define('Video', {
extend: 'Ext.data.Model',
fields: ['id', 'title']
});
myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
proxy: {
type: 'ajax',
url : 'http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc',
reader: {
type: 'jsonp',
root: 'items'
}
}
});
Thanks in advance!
Ed.
JsonP requires the server to wrap the returned data in a JS function call. The common contract is to pass a parameter named 'callback' to the server to allow for unique names and avoid name clashes on the client.
Calling the URL http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc&callback=myCallback in the browser shows that YouTube support this convention:
Ext supports JsonP via the Ext.data.proxy.JsonP proxy class. The reader is a standard JSON reader and not JsonP specific, you only need to account for the data structure returned from the server (set root to data.items).
The working code looks like this:
var myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
proxy: {
type: 'jsonp',
url : 'http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc',
reader: {
type: 'json',
root: 'data.items'
}
},
listeners: {
load: function(store, records) {
Ext.each(records, function(rec) {
console.log(rec.get('title'));
});
}
},
autoLoad: true
});

Extjs throws exception "realize was called with invalid remote-data" on successful creation of record

I am using extjs in a monorail application. I am using a JsonStore to persist data back to my controller. I have read, update and delete working properly. But I cannot seem to figure out how to format my response back on creates. Currently, Firebug gives me the following error:
uncaught exception:
Ext.data.DataReader: #realize was
called with invalid remote-data.
Please see the docs for
DataReader#realize and review your
DataReader configuration.
I am flummoxed about WTF this error means. Anyone have pointers? Relevant bits of code below:
var proxy = new Ext.data.HttpProxy({
api: {
read: '../foo/bar.rnr',
create: '../foo/CreateBar.rnr',
update: '../foo/UpdateBar.rnr',
destroy: '../foo/DeleteBar.rnr'
}
});
var writer = new Ext.data.JsonWriter({
encode: true,
writeAllFields: true,
listful: true,
destroyRecord: function(rec) {
return this.toHash(rec);
}
});
var store = new Ext.data.JsonStore({
autoLoad: true,
autoSave: false,
url: '../foo/bar.rnr',
method: 'get',
baseParams: { Id: pageParameters.Id },
proxy: proxy,
writer: writer,
id: 'Id',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'Name', type: 'string' },
{ name: 'Note', type: 'string', defaultValue: null }
]
});
My current response looks like this, but this is after a lot of trial and error, so it is prolly hosed.
{"success":true,"message":"OK!","undefined":[]}
You'll need to return records in the returning json object.
Go to the following example from My book, Ext JS in Action, that shows how to use data writer for crud actions.
http://extjsinaction.com/examples/chapter08/usingWriterWithHttpProxy.html
Right click to insert a new record. Observe the Ajax req's from firebug and you'll see it in action.

Resources