extjs using jsonp,Accessing data from remote url - extjs

with extjs,i m runnig the server from one system,giving the url in another system and i m using JSONP in extjs ver:4.02,when i check in response i m getting data in json format,when i try to print in console or Store im not getting..here is my extjs code...
<script type="text/javascript">
Ext.Ajax.cors = true;
Ext.Ajax.useDefaultXhrHeader = false;
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['empid', 'name', 'email']
});
var myStore = Ext.create('Ext.data.Store', {
model: 'User',
autoLoad:true,
proxy: {
type: 'jsonp',
// url : 'data/tagfamily.json',
url:'http://192.168.7.70:8080/palamanagement/user/getAllRecords',
},
listeners:{
'load':function( store, records, successful, eOpts ){
alert(records);
console.log(records);
}
}
});

You literally have to return something like the following:
someCallback({
users: [
{
id: 1,
name: "Ed Spencer",
email: "ed#sencha.com"
}
]
});
So you already have the JSON the way you need it; you just need your server response to wrap the JSON in the callback so that the JSONP proxy can execute and load your store with data.
Therefore, when handling the JSONP request, your server's script needs to recognize the "callback" param that is sent as a part of the request. It then needs to use the value of this param to wrap your JSON response.
Be sure to read the docs that both myself and Oguz have posted: they outline the requirement pretty well. But if you don't respond with a callback, you'll never get your standard JSON response to work with the JSONP proxy.

When you request from DOMAIN-A to DOMAIN-B, you should provide a call back function in proxy definition. The callback function will use in after request complete.
For instance, in Flickr REST service, there is jsoncallback parameter which we should give our function name in order to complete our request. In this way, our request url will be:
.../?jsoncallback=ourFunction
To be able to provide our function name, there is a property in ExtJS which is callbackKey.
Like so:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['empid', 'name', 'email']
});
Ext.data.JsonP.request('http://api.flickr.com/services/feeds/photos_public.gne', {
callbackKey: 'jsoncallback',
callback: ourFunctionName
});
or
Ext.data.JsonP.request('http://api.flickr.com/services/feeds/photos_public.gne', {
callbackKey: 'jsoncallback',
callback: function(data) {
...
}
});
PS: I know, you will not find callback property in doc but just to be sure there is. Check ext-all-debug-w-comments.js file, line 108486
Flickr Callback Function
JsonP callbackKey

Related

Accessing additional properties from JSON received through store's load method

I have a grid that loads data via a JSON store, however there are some additional properties beyond the records themselves that I need to access. Here's an example of what the JSON data looks like:
{
success: true,
records: [
{id: 1, name: 'bob'},
{id: 2, name: 'fred'}
],
extraProperty: 'foo'
}
I need to access that extraProperty when the grid data is loaded. So I assume I'd want to a callback, like so:
store.load({
callback: function (records, operation, success) {
//somehow access extraProperty here
}
});
I'm not sure what to do inside that callback. The operation variable, an Ext.data.operation.Operation object, has a private method called getResponse(). It returns an object in Chrome that has a responseJson property, but in IE it instead has a responseText property that needs to be decoded. So I could handle both scenarios, but since it's a private method I don't really want to rely on it in the first place. Any ideas?
Use the keepRawData config on the reader.
store.load({
callback: () => {
const { extraProperty } = store.getProxy().getReader().rawData;
}
});
Depending on your needs, you may also want to look at preserveRawData as well.
did you tried on the store level, something like below
under proxy in the reader config section
proxy: {
type: 'ajax',
actionMethods: {
read: 'GET'
},
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
api: 'your url',
reader: {
extraProperty: 'extraProperty'
}
}

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.

Angularjs strongloop custom method

I have defined a custom method in my strongloop application, which returns the right datas when I test it through the Api explorer.
I then generated the an angularjs service thanks to "lb-ng".
When I send a request with this custom method through angular I get this error :
Error in resource configuration for action `list`. Expected response to contain an object but got an array (Request: GET http://**myip**/api/Questions)
The thing is it should call this address instead :
http://**myip**/api/Questions/4/0
It used to work at some point, before a regenerated an angular service with lb-ng
Here is the method registration in strongloop :
Question.remoteMethod(
'list', {
http: {path: '/:lang/:start/', verb: 'get'},
accepts: [
{arg: 'lang', type: 'number'},
{arg: 'start', type: 'number'}
],
returns: {arg: 'questions', type: 'array'},
description: ['Returns an array obj the latest added questions filters by language and categories']
}
)
And here is the calling test in angular in my homeController :
function getQuestions(langId, start) {
Question.list(langId, start)
.$promise
.then(function(questionsList) {
$scope.questions = questionsList.questions;
}
);
}
getQuestions(4, 0);
Do you have any idea why the method is not calling the address with arguments ?
I am pretty sure that request parameters need to be on an object (as per the REST API use via explorer) as follows:
Question.list({lang:langId, start: start}).$promise.then(...)
I would also suggest generating the docular docs for the angular SDK as these help clarify things.
In the service file that was generated look for the list method and add/set the isArray parameter as true, it should be something like this:
"list": {
...
isArray: true,
...
}

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

Resources