Sencha Touch 2 Load store crashs - extjs

Hello i have the following problem:
After i generate the AP and install it on my phone the requisition store.load breaks in this specific store called CHAMADOS, but when i close the app and restart, it does not crash and bring me all the informations in the list...
It seems that the .load requires bring me the informations in the first time.
When i close and open it again the cache informations required before is add to the list, but the load required on the restart APP does not work.
It crashs and dont add the items to the LIST, but the store has data because on restart it appears, i have others store in this app and they work fine!
On brownser its fine, the problem is in the APK
Here is the view
{
height: '60%',
ui:'round',
style:'padding:18px 0; background:#FFF;',
xtype: 'dataview',
id: 'feedListagemChamados',
store: 'Chamados',
itemTpl: '<span>{nom_chamado}</span> '
}
Here is the store
Ext.define('WE3Chamados.store.Chamados', {
extend: 'Ext.data.Store',
config: {
model: 'WE3Chamados.model.Chamado',
autoLoad: true,
proxy: {
type: 'jsonp',
url: 'http://LINK?cod_usuario='+localStorage.getItem("usuarioId"),
callbackKey: 'callback',
reader: {
type: 'json',
rootProperty : 'chamados',
successProperty: 'success'
}
}
}});
Here is where i call the store to load (CONTROLLER)
showListaChamados: function (direcao) {
this.cleanApp();
store = Ext.getStore('Chamados').load();
store.load({
scope : this,
callback : function(records, operation, success) {
***IT BREAKS HERE ON RETURN***
Ext.Msg.alert('Opps', records[0].data.nom_usuario, this);
Ext.Viewport.animateActiveItem(this.getChamadoView(), this.getSlideTransition(direcao));
}
});
Ext.Msg.alert('Opps', store.data, this);
}
Here is the model
Ext.define('WE3Chamados.model.Chamado', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'cod_chamado'
},
{
name: 'nom_chamado'
},
{
name: 'des_chamado'
},
{
name: 'cod_equipe'
},
{
name: 'dat_cadastro'
},
{
name: 'dat_previsao'
},
{
name: 'dat_necessaria'
},
{
name: 'num_prioridade'
},
{
name: 'cod_projeto'
},
{
name: 'nom_usuario'
},
{
name: 'cod_status'
},
{
name: 'nom_projeto'
},
{
name: 'des_equipe'
},
{
name: 'nom_status'
},
{
name: 'nom_cliente'
},
{
name: 'cod_usuario'
},
{
name: 'cod_usuario_responsavel'
}
]
}});

I found the problem, it was in the localStorage.getItem("usuarioId") its not sendind it by the get, because it is after login, i think there is a bug in the js or its so fast that the comand to send the link cant get the localStorage.getItem.
Im trying using php SESSION now.

Related

PullRefresh plugin of a List doesn't handle ChainedStore possibility

Using Ext JS 7.1 Modern, I have prepared an example to show the problem.
When I have remote filters on my main store, binding the dataview.List to a ChainedStore correctly handles my local filtering. However, when I also add a PullRefresh plugin to the list, I get an error during pull refresh. I see from the source code that the plugin doesn't consider the possibility that a list's store can be a ChainedStore.
I have tried to explain the problem with a Sencha Fiddle and also attached the code below.
I have temporarily solved the problem by overriding the fetchLatest and onLatestFetched methods of Ext.dataview.pullrefresh.PullRefresh plugin, to use the source store if the list's store is a ChainedStore. But I believe the source code must be updated to handle this case.
app.js
Ext.define('App.model.Test', {
extend: 'Ext.data.Model',
fields: ['id', 'firstName', 'lastName']
});
Ext.define('App.store.Test', {
extend: 'Ext.data.Store',
alias: 'store.teststore',
model: 'App.model.Test'
});
Ext.define('App.viewmodel.Test', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.test',
data: {
query: ''
},
stores: {
test: {
type: 'teststore',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'names.json',
reader: {
type: 'json',
rootProperty: 'data'
}
},
remoteFilter: true,
filters: {
property: 'id',
value: 1
}
},
chained: {
type: 'chained',
autoLoad: true,
source: '{test}'
}
}
});
Ext.define('App.controller.TestController', {
extend: 'Ext.app.ViewController',
alias: 'controller.testcontroller',
doSearch: function (field) {
var list = this.lookup('list'),
store = list.getStore(),
value = field.getValue();
if (Ext.isEmpty(value)) {
store.removeFilter('firstName')
} else {
store.filter([{
property: 'firstName',
value: value,
operator: 'like'
}])
}
}
});
Ext.define('App.dataview.TestList', {
extend: 'Ext.dataview.List',
xtype: 'testlist',
viewModel: {
type: 'test'
},
plugins: [{
type: 'pullrefresh',
mergeData: false
}],
emptyText: 'Name not found',
bind: {
store: '{chained}'
},
itemTpl: '<div class="contact">{id} <b>{firstName} {lastName}</b></div>'
});
Ext.define('App.MainView', {
extend: 'Ext.Panel',
controller: 'testcontroller',
fullscreen: true,
viewModel: {
type: 'test'
},
items: [{
xtype: 'searchfield',
ui: 'solo',
placeholder: 'Search names',
listeners: {
buffer: 500,
change: 'doSearch'
},
bind: {
value: '{query}'
}
}, {
reference: 'list',
xtype: 'testlist'
}]
})
Ext.application({
name: 'App',
mainView: 'App.MainView'
});
names.json
var data = [{
id: 1,
firstName: 'Peter',
lastName: 'Venkman'
}, {
id: 2,
firstName: 'Raymond',
lastName: 'Stantz'
}, {
id: 3,
firstName: 'Egon',
lastName: 'Spengler'
}, {
id: 4,
firstName: 'Winston',
lastName: 'Zeddemore'
}]
var results = data.filter(function(record) {
if (params.filter) {
return record.id > params.filter[0].value
}
})
return {
"success": true,
"data": results
}
App.override.dataview.pullrefresh.PullRefresh:
Ext.define('App.override.dataview.pullrefresh.PullRefresh', {
override: 'Ext.dataview.pullrefresh.PullRefresh',
privates: {
fetchLatest: function() {
const store = this.getStore().isChainedStore ? this.getStore().getSource() : this.getStore()
store.fetch({
page: 1,
start: 0,
callback: this.onLatestFetched,
scope: this
});
},
onLatestFetched: function(newRecords, operation, success) {
var me = this,
list = me.getList(),
store = list.getStore().isChainedStore ? list.getStore().getSource() : list.getStore(),
length, toInsert,
oldRecords, newRecord, oldRecord, i;
if (success) {
if (me.getMergeData()) {
oldRecords = store.getData();
toInsert = [];
length = newRecords.length;
for (i = 0; i < length; i++) {
newRecord = newRecords[i];
oldRecord = oldRecords.getByKey(newRecord.getId());
if (oldRecord) {
oldRecord.set(newRecord.getData());
}
else {
toInsert.push(newRecord);
}
}
store.insert(0, toInsert);
}
else {
store.loadRecords(newRecords);
}
me.setLastUpdated(new Date());
}
me.setState('loaded');
list.fireEvent('latestfetched', me, toInsert || newRecords);
if (me.getAutoSnapBack()) {
me.snapBack(true);
}
}
}
})
Thanks in advance
Since this post, instead of being a question, was a bug report with a possible solution, it has been posted to Ext JS 7.x Community Forums\Ext JS 7.x Bugs.
The above solution, that overwrites the plugin where source store is needed, works if anyone comes across the same issue.

ExtJs Grid Auto Refresh using REST Proxy

I have tried to refresh the Grid every 5 or 10 seconds which is using REST Proxy, but the grid is not getting refreshed more than once. Please find the code which we have tried.
Ext.define('App.Store.DeviceStore', {
extend: 'Ext.data.Store',
requires: [
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'app.store.DeviceStore',
model: 'App.model.DeviceModel',
activeRefreshTask:false,
pageSize: 5,
autoLoad: {
pageSize: 5
}
}, cfg)]);
},listeners:{
'load':function(store,records,successful,operation){
if(successful === true && store.activeRefreshTask === false){
var task = {
identifyId: 'deviceListStore',
run: function() {
if (App.app._currentPage == 'devicesform') {
store.reload();
} else {
Ext.TaskManager.stop(this);
}
},
interval: '10000'
}
Ext.TaskManager.start(task);
store.activeRefreshTask = true;
}
}
}
});
The model for the above store is
Ext.define('App.model.DeviceModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.String'
],
proxy:{
type:'rest',
reader: {
type: 'json',
rootProperty: 'data',
totalProperty:'total'
},
useDefaultXhrHeader: false,
headers:{'Content-Type':'application/json'},
api: {
read: 'url given gere'
}
},
fields: [
{
type: 'string',
name: 'id'
},
{
type: 'string',
name: 'name'
},
{
type: 'string',
name: 'desc'
},
{
type: 'string',
name: 'ipAddr'
}
]
});
I have found the issue , You have passed the interval as string in place lo number.
just change to interval: '10000' to inteval: 10000 and your taskrunner will runs fine.
var runner = new Ext.util.TaskRunner(),
updateStore , task;
updateStore = function() {
if (App.app._currentPage == 'devicesform') {
store.load();
} else {
Ext.TaskManager.stop(this);
}
};
task = runner.start({
run: updateStore ,
interval: 1000
});
probably your store.reload is sending again the same params on the request, so with a request that not change nothing changes.

Sencha Touch 2 and Ext.Direct API calling - Login Form

So the main question is: Does any one know how I need to change my calling method to be compatible with Sencha Touch 2?
Description:
I have a large Extjs application with a C# backend. I already have a mobile site with pages, but none of them require submitted form data. The trouble came when trying to create a login page.
On the desktop, using extjs and Ext.direct, there are login forms and they work fine, but the same coding patterns don't seem to work with Sencha Touch 2.
Ext.define('PF.view.phone.login.Form', {
extend: 'Ext.form.Panel',
alias: 'widget.phoneloginform',
requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img'],
autoheight: true,
initialize: function () {
this.build();
this.callParent();
Ext.apply(this, {
api: {
submit: LoginActionImpl.login
}
});
scope: this
},
config: {
title: 'Login',
items: [
{
xtype: 'label',
html: 'Client Login',
itemId: 'clientLoginLabel',
style: 'text-align: left; font-size: 1.1em',
margin: '10 0 20 0'
}, {
xtype: 'fieldset',
/*Temporary style*/
margin: '10 17% 10 17% ',
items: [
{
xtype: 'textfield',
itemId: 'loginUsername',
name: 'loginUsername',
label: 'Username',
required: true
}, {
xtype: 'passwordfield',
itemId: 'loginPassword',
name: 'loginPassword',
label: 'Password',
required: true
}, {
xtype: 'toolbar',
layout: {
pack: 'right'
},
ui: 'plain',
items: [{
xtype: 'button',
itemId: 'loginButton',
text: 'Login',
ui: 'confirm'
}, {
xtype: 'button',
itemId: 'clearButton',
text: 'Clear',
ui: 'decline'
}]
}
]
}
]
},
build: function () {
this.down('#clearButton').setHandler(this.clear);
this.down('#loginButton').setHandler(this.login);
},
clear: function (btn, evt) {
btn.up('phoneloginform').reset();
},
login: function (btn, evt) {
/* Need help here */
/* Below is what would normally be used in the rest of the application */
this.submit({
success: this.onLoginSuccess,
failure: function (form, action) {
this.onLoginFailure(action.result);
},
scope: this
});
},
onLoginSuccess: function (arguments) {
Ext.dispatch('login/success');
},
onLoginFailure: function (result) {
// Here we need to check the actual results to determine why the login failed.
//
// A return code of -2 indicates account locked - otherwise we just assume an invalid attempt.
//
if (result.returnCode == -2) {
this.getComponent("loginUsername").markInvalid(t('ptl_mbl_user_status_locked_password'));
this.getComponent("loginUsername").markInvalid(t('ptl_mbl_user_status_locked_password'));
}
else {
this.getComponent("loginUsername").markInvalid(t('wms_username_password_incorrect_error'));
this.getComponent("loginPassword").markInvalid(t('wms_username_password_incorrect_error'));
}
Ext.dispatch('login/fail', result.returnCode);
},
getUsername: function () {
if (this.username) {
this.username = this.getValues()['#loginUsername'];
}
},
getPassword: function () {
if (this.password) {
this.password = this.getValues()['#loginPassword'];
}
}
});
The method of the C# method is:
[DirectMethodForm]
public JObject login(HttpRequest request)
{
String username = request["loginUsername"];
String password = request["loginPassword"];
this.setDB(request["db"]);
int loginReturnCode = this.getUserDetailsService().login(username, password, this.getDB(), true);
JObject jsonObject;
if (loginReturnCode == 0)
{
jsonObject = new JObject(
new JProperty("loginUsername", username),
new JProperty("loginPassword", password),
new JProperty("db", this.getDB()),
new JProperty("success", true));
}
else
{
jsonObject = new JObject(
new JProperty("errors", new JArray(new[] { loginReturnCode.ToString() })),
new JProperty("returnCode", loginReturnCode),
new JProperty("failed", true));
}
return jsonObject;
}
and what I'm trying to reuse so that can't be changed.
Stepping through the code in the browser, the issue comes during the "urlAppend" method in the "sencha-touch-all.js" file where the "url" parameter is null, so the call never reaches the C# code.
urlAppend : function(url, string) {
if (!Ext.isEmpty(string)) {
return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
}
return url;
},
However, I've never needed to set that variable before, in using Ext.direct. I don't have a separate web service, so actual web service calls are not available.
Thanks in advance.

How to create Grid in sencha touch 2.3.0 populate data from a REST webservice

I need to display report in Grid / Table in Sencha Touch 2.3.0. Is there any build in function to do so.
The store needs to populate data from a REST webservice call.
For loading data you can use Ext.data.Store configured with REST proxy Ext.data.proxy.Rest
For displaying data from store you can use Ext.grid.Grid of Ext.dataview.DataView
I do this all the time with something like this:
(Though I haven't worked with the Grid, I'm quite sure the same principles apply...)
Ext.define('App.controller.GridController', {
extend : 'Ext.app.Controller',
config: {
refs: {
getApiButton: 'button[action=getApiData]'
},
control: {
'getApiButton' : {
tap : 'onButtonTap'
}
}
},
onButtonTap : function(field, value) {
var that = this;
Ext.Ajax.request({
url : someWebServiceUrl,
method: 'GET',
success: function (result, request) {
var res = Ext.decode(result.responseText);
if (res.success === true && res.data != false) {
var recipient = {
name: res.data[0].displayname,
picId: res.data[0].pictureid,
gender: res.data[0].gender
};
var mod = Ext.define('App.model.GradingPopModel', {
extend: 'Ext.data.Model',
config: {
fields: [
'name',
'picId',
'gender'
]
}
});
/* == this is probably where you want to make your changes to apply the model to the grid template
the sencha website has this:
data: {'items': [
{ 'name': 'Lisa', "email":"lisa#simpsons.com", "phone":"555-111-1224" },
{ 'name': 'Bart', "email":"bart#simpsons.com", "phone":"555-222-1234" },
{ 'name': 'Homer', "email":"home#simpsons.com", "phone":"555-222-1244" },
{ 'name': 'Marge', "email":"marge#simpsons.com", "phone":"555-222-1254" }
]}
*/
var store = Ext.create('Ext.data.Store', {
model: mod,
storeId:'recipStore'
});
store.add(recipient);
store.setData(recipient);
store.load();
var gridView = Ext.ComponentQuery.query('#gridViewId')[0];
gridView.setStore(store);
}
},
failure: function (result, request) {
console.log('api call was a failure');
},
scope: this
});
}
});
Now of course your data won't have "displayname, gender" etc.. but you should get the point.
I also found a working example here (I find it very sad that Sencha allows broken demos on their own website): http://demo.rasc.ch/eds/touch23/grid/grid/index.html

Ext.data.LocalStorage not working on Offline Mode

Im now studying Sencha Touch 2 and doing some Research on Ext.data.LocalStorage that can be use in Offline Mode.
I tried to follow this turorial
Sencha Touch 2 Local Storage
and just updated the code from Github - RobK/SenchaTouch2-LocalStorageExample or riyaadmiller/LocalStorage and modified Store url using my own WCF Rest
but i cant get LocalStorage working on offline mode.I have no issue on running the app Online. I also tried to debug it on Chrome developer tool but LocalStorage always get 0 data. I used Chrome/Safari Browser and also build the apps as Android using Phonegap build and still not working.
Did I miss something?
Does anyone can provide the details to deal with this Issue.
Below is my code:
Store:
Ext.define('Local.store.News', {
extend:'Ext.data.Store',
config:{
model: 'Local.model.Online',
proxy:
{
type: 'ajax',
extraParams: { //set your parameters here
LookupType: "Phone",
LookupName: ""
},
url: 'MY WCF REST URL',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
reader:
{
type: 'json'
, totalProperty: "total"
},
writer: { //Use to pass your parameters to WCF
encodeRequest: true,
type: 'json'
}
},
autoLoad: true
}
});
Offline Model:
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});
Online Model:
Ext.define('Local.model.Online', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "Name", type: "string" },
{ name: "Description", type: "string" }
]
}
});
Controller:
Ext.define('Local.controller.Core', {
extend : 'Ext.app.Controller',
config : {
refs : {
newsList : '#newsList'
}
},
/**
* Sencha Touch always calls this function as part of the bootstrap process
*/
init : function () {
var onlineStore = Ext.getStore('News'),
localStore = Ext.create('Ext.data.Store', { storeid: "LocalNews",
model: "Local.model.Offline"
}),
me = this;
localStore.load();
/*
* When app is online, store all the records to HTML5 local storage.
* This will be used as a fallback if app is offline more
*/
onlineStore.on('refresh', function (store, records) {
// Get rid of old records, so store can be repopulated with latest details
localStore.getProxy().clear();
store.each(function(record) {
var rec = {
name : record.data.name + ' (from localStorage)' // in a real app you would not update a real field like this!
};
localStore.add(rec);
localStore.sync();
});
});
/*
* If app is offline a Proxy exception will be thrown. If that happens then use
* the fallback / local stoage store instead
*/
onlineStore.getProxy().on('exception', function () {
me.getNewsList().setStore(localStore); //rebind the view to the local store
localStore.load(); // This causes the "loading" mask to disappear
Ext.Msg.alert('Notice', 'You are in offline mode', Ext.emptyFn); //alert the user that they are in offline mode
});
}
});
View:
Ext.define('Local.view.Main', {
extend : 'Ext.List',
config : {
id : 'newsList',
store : 'News',
disableSelection : false,
itemTpl : Ext.create('Ext.XTemplate',
'{Name}-{Description}'
),
items : {
docked : 'top',
xtype : 'titlebar',
title : 'Local Storage List'
}
}
});
Thanks and Regards
1) First of all when you creating record and adding into store, the record fields should match the model fields of that store.
Here you creating record with field name, but Local.model.Offline didn't name field
var rec = {
name : record.data.name + ' (from localStorage)'
};
This is what you need to do within refresh
localStore.getProxy().clear();
// Also remove all existing records from store before adding
localStore.removeAll();
store.each(function(record) {
console.log(record);
var rec = {
ID : record.data.ID,
LookupName : record.data.Name + ' (from localStorage)',
LookupDescription : record.data.Description
};
localStore.add(rec);
});
// Don't sync every time you add record, sync when you finished adding records
localStore.sync();
2) If specify idProperty in model which is using localStorage, then record will not be added into localStorage.
Model
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
// idProperty removed
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});

Resources