why I can't get JSON from server in ExtJs4? - ajax

I wanna get JSON from the server.And here is the django server view function:
def showChart(request):
data = [{"id":1, "name":"Tom", "email":"a#a.com"}, {"id":2, "name":"Bosh", "email":"c#c.com"}]
return HttpResponse(json.dumps(data), mimetype="application/json");
Obviously, showChart() will return a json.
My frontend extjs4 code:
Ext.onReady(function() {
Ext.define('ProductionInfo', {
extend: 'Ext.data.Model',
fields: ['email', 'id', 'name']
});
var store_new = Ext.create('Ext.data.Store', {
model: 'ProductionInfo',
proxy: {
type: 'ajax',
url : 'http://localhost:8000/production_data',
reader: {
type: 'json'
}
}
});
store_new.load();
alert(store_new.getCount());
});
But the alert dialog shows '0', while the right answer is '2'. So why I can't get JSON from server? (I can get the right JSON through a GET request in Chorme and Firefox)

You could check my sample: https://github.com/lucassus/extjs4-account-manager
It's rails application but json mechanism is very similar.
Basically you have to define a model with valid proxy: https://github.com/lucassus/extjs4-account-manager/blob/master/app/assets/javascripts/app/model/User.js
and a store which will have model attribute: https://github.com/lucassus/extjs4-account-manager/blob/master/app/assets/javascripts/app/store/Users.js

Related

Typeahead.js JSON response not rendering

I'm trying to integrate Twitter Typeahead into my Laravel (4.2.11) project (with Bootstrap 2.3.2).
I have results being returned as JSON (checked with Fiddler), but a single "undefined" is always displayed instead.
If I enter a search query that doesn't return any results, the "No Results" is displayed correctly.
//Simple query in Laravel
Route::get('/sidebar/clients/{q}', function($q)
{
$companies = DB::table('ViewCompanies')->select(array('CompanyID', 'FullCompanyName'))
->where('FullCompanyName', 'like', '%'. $q .'%')->get();
return Response::json(array('companies' => $companies));
});
//Javascript in page
var clients = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('FullCompayName'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/sidebar/clients/%QUERY',
filter: function (parsedResponse) {
// parsedResponse is the array returned from your backend
console.log(parsedResponse);
return parsedResponse;
}
}
});
clients.initialize();
$('#clients .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 3,
},
{
name: 'clients',
valueKey: 'CompanyID',
displayKey: 'FullCompanyName',
source: clients.ttAdapter(),
templates: {
empty: [
'<div class="tt-empty-message">',
'No Results',
'</div>'
],
header: '<h3 class="tt-tag-heading tt-tag-heading2">Matched Companies</h3>'
}
});
My console log using the above code:
what is the output of the parsedResponse you are logging? I think DB::table returns an object, not an array. Try to replace the response like this:
return Response::json(array('companies' => $companies->toArray()));
Then log the results and format them in the "filter" function in the Bloodhound object.
Hope it helps!
Thanks to Eduardo for giving me the idea of needing to parse my JSON into a JS array.
Doing a search revealed these two questions:
Twitter Typeahead.js Bloodhound remote returns undefined
Converting JSON Object into Javascript array
from which I was able to devise my one-line solution (full remove filter show):
filter: function (parsedResponse) {
console.log(parsedResponse);
var parsedResponse = $.map(parsedResponse, function(el) { return el; });
return parsedResponse;
}

ExtJS 5.0.1: Unable to use anonymous models in a Session

I'm getting this error:
[E] Ext.data.Session.checkModelType(): Unable to use anonymous models
in a Session
when trying to use a Session when binding a Grid with a Store via ViewModel:
ViewModel:
Ext.define('App.view.gridViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.gridview',
stores:{
gridstore: {
model: 'gridView',
autoLoad: true,
//This triggers the Exception:
session: true,
listeners: {
beforeload: function(store, operation, eOpts) {
var oProxy = this.getProxy();
oProxy.setExtraParams({
tableName: 'dbo.SomeTable'
, identityKey: "id"
, primaryKey: ["id"]
, mode: "readonly"
, lang: "es"
, output: 'json'
});
}
}
}
}
});
View:
Ext.define('App.view.gridView', {
extend: 'Ext.form.Panel',
//...
viewModel: {
type: 'gridview'
},
controller: 'gridview',
// Create a session for this view
session:true,
items: [{
xtype: 'grid',
reference: 'myGrid',
bind: '{gridstore}',
columns: [
//...
]
}]
//...
});
Model's data is fetch through a Proxy:
Model:
Ext.define("App.model.gridView", {
extend: 'Ext.data.Model',
schema: {
namespace: 'App.model'
},
proxy: {
//proxy remote api stuff......
}.
idProperty: 'id'.
primaryKeys: 'id'.
fields: [
//fields
]
});
I have no idea what an anonymous model is and I haven't found anything related in the web, any ideas?
Thanks in advance!
The reason seems to be that in my Server's response I have a JSON Object called "metaData", which collides with the one available in JSON Reader:
Response MetaData
The server can return metadata in its response, in addition to the
record data, that describe attributes of the data set itself or are
used to reconfigure the Reader. To pass metadata in the response you
simply add a metaData attribute to the root of the response data. The
metaData attribute can contain anything, but supports a specific set
of properties that are handled by the Reader if they are present:
http://docs.sencha.com/extjs/5.0/apidocs/#!/api/Ext.data.reader.Json
The curious thing is that I don't use any of the available metaData options for JSON Reader, nothing related to any anonymous model, therefore this might be considered a bug

Angularjs multiple ajax requests optimization

I am still learning Angular JS and have this controller which is making two ajax requests to the lastfm api using different parameters. I want to know when each request has been finished, so that I can display a loading indicator for both requests. I have researched it and read about promises and the $q service but cant get my head around how to incorporate it into this. Is there a better way to set this up? and how can I know when each request is done. Thanks.
angular.module('lastfm')
.controller('ProfileCtrl', function ($scope, ajaxData, usersSharedInformation, $routeParams) {
var username = $routeParams.user;
//Get Recent tracks
ajaxData.get({
method: 'user.getrecenttracks',
api_key: 'key would go here',
limit: 20,
user: username,
format: 'json'
})
.then(function (response) {
//Check reponse for error message
if (response.data.message) {
$scope.error = response.data.message;
} else {
$scope.songs = response.data.recenttracks.track;
}
});
//Get user info
ajaxData.get({
method: 'user.getInfo',
api_key: 'key would go here',
limit: 20,
user: username,
format: 'json'
})
.then(function (response) {
//Check reponse for error message
if (response.data.message) {
$scope.error = response.data.message;
} else {
$scope.user = response.data.user;
}
});
});
I have this factory which handles all the requests
angular.module('lastfm')
.factory('ajaxData', function ($http, $q) {
return {
get: function (params) {
return $http.get('http://ws.audioscrobbler.com/2.0/', {
params : params
});
}
}
});
Quite easy using $q.all(). $http itself returns a promise and $q.all() won't resolve until an array of promises are resolved
var ajax1=ajaxData.get(....).then(....);
var ajax2=ajaxData.get(....).then(....);
$q.all([ajax1,ajax2]).then(function(){
/* all done, hide loader*/
})

Initializing an angular resource object instance without calling the server

In Backbone.js, one can instantiate a model with pre-existing JSON data by using
var user = new Backbone.Model({ name: "John Doe", age: 30 });
And then perform updates with a single call
user.save({ age: 31 }, { success: successCallback, error: errorCallback });
This comes handy in all sorts of scenarios, such as when that data is already available on the client through caching or pre-populated templates (like using <%= raw #user.to_json %> in rails erb templates).
I'm curious to know how this is done when using $resource with Angular.js. Right now, I have a situation where my data is cached on the client before the $resource is created, and I'd like to update it without making an extra GET call to populate the object:
app.factory('User', ['$resource', function($resource) {
return $resource('/users/:user_id.json', { user_id: '#id' }, {
get: { method: 'GET' },
save: { method: 'PUT' },
create: { method: 'POST' },
destroy: { method: 'DELETE' }
});
}]);
And somewhere in my controller I'd like to just update an existing user without fetching it from the server:
app.controller('UsersController', ['User', function(User) {
// somehow initialize a user from an existing
// object, say { name: "John Doe", age: 30 }
user.age = 31
user.$save()
// instead of doing this
User.get({ user_id: 100 }, function(user, respHeaders) {
user.age = 31
user.$save()
});
}]);
I'm probably still in the Backbone mindset, but I'm really curious if I'm approaching this all wrong. Thanks.
$resource gives the option to create a new user like you would with any object:
var user = new User({name : 'John Doe', age: 30});
user.age = 32;
user.$save();
Resource Docs

How to read inline data written in a store from a controller in Sencha Touch 2.0 mvc

I am learning about Sencha so i have very basilar question.
I am trying to build a simple mvc application, with controller, views model and store.
I have this nmodel
Ext.define('rpc.model.Studenti', {
Extend: 'Ext.data.Model',
fields: [
{ name: 'cognome', type: 'string' },
{ name: 'previsione', type: 'string' }
]
});
this store (with inline data)
Ext.define('rpc.store.Studenti', {
model: 'rpc.model.Studenti',
storeId: 'gruppoStore',
autoLoad: true,
data: [
{cognome: 'uno', previsione: 'aaa'},
{cognome: 'due', previsione: 'bbb'},
{cognome: 'tre', previsione: 'ccc'}
]
});
the controller
Ext.define('rpc.controller.Home', {
extend: 'Ext.app.Controller',
stores: ['Studenti'],
models: ['Studenti'],
views: ['home.Fila','home.Griglia','home.Previsio'],
store: 'gruppoStore',
init: function() {
this.control({
'griglia button': {
tap: this.faqualcosa
}
});
},
faqualcosa: function(button){
...
var gruppoStoreMgr=this.getStudentiStore();
alert (gruppoStoreMgr.count());
for (var key in gruppoStoreMgr) {
//alert (key);
}
alert (gruppoStoreMgr.storeId);
alert (gruppoStoreMgr.isInstance);
//alert (gruppoStoreMgr.data);
alert (gruppoStoreMgr.autoLoad);
for (var key in gruppoStoreMgr.data[0]) {
//alert ("0"+key);
}
for (var key in gruppoStoreMgr.data[1]) {
//alert ("1"+key);
}
}
});
Please, what is the right way to access in function faqualcosa to the store data?
I've been able to have something like an instance (sure it is very near...) of the model with var gruppoStoreMgr=this.getStudentiStore(); but i have no trace of the data i've written in the store ("uno", "due"....). How to get that data? How to have in a controller funcion an object who refers to the real data in the store?
this.getStudentiStore().data.items
That is the most direct way to get to the data. It returns an array of the model records. If that's what you're looking for.
for(var i = 0; i < this.geStudentiStore().getCount(); i++ ) {
var record = this.getStudentiStore().getAt(i)
console.log(record.get('cognome'));
}
That should print out all the "cognomes"

Resources