Fetching JSON response data from JSON array through store - sencha-touch-2

We get a response in JSON format but we're unable to fetch and print the data.
var dstore = Ext.getStore('DomesticStore');
dstore.sync();
dstore.load();
console.log(dstore.getData().items);
// this line prints the output but unable to fetch inside array data.

I have an application that gets JSON data.
When you get the store call the on method. Then access the data by using the records array.
var Store1 = Ext.getStore('DomesticStore').on('load', function (store, records, successful, operation, eOpts) {
if(successful == false){
console.log("Could not load store. ");
}
var e;
for (var i = 0; i < records.length; i++) {
e = records[i];
console.log(e.get('elementname'));
}
});
This will get go through the JSON array and get each value of whatever the field name is.
My JSON data looks like this
{
"countries": [
{
"name": "United States",
"2001": 128500000,
"2002": 141800000,
"2003": 160637000,
"2004": 184819000,
"2005": 203700000,
"2006": 229600000,
"2007": 249300000,
"2008": 261300000,
"2009": 274300000,
"2010": 278900000,
leaf: true
}
]
}
I use that code to get each country from the records array and then the name field of each.

Related

Datatables mDataProp: val param undefined

I'm working on implementing a custom filter value where existing html tags are stripped away for each applicable table column values.
(The reason is that filtering the data also accounts for values inside the html tags, and this is not desired.)
This is a legacy code base, using datatables v1.9.0.
The table is constructed using params, such as aoColumns, aaData.
For table data is using array of arrays: i.e:
aaData = [
['12450','<a href='javascript:doStuff(123, 456)>value2</a>', 'User 1', '$500'],
['12455','...','...','...'],
['12462','...','...','...'],
['12314','...','...','...'],
[...],
...
]
Table has to use mDataProp for applicable aTargets
The function signature is:
tableOptions["aoColumnDefs"] = [
{
"mDataProp": function (source, type, val) {
console.log("source ", val); // This returns: row array
console.log("type ", type); // This returns each type (except for 'set')
console.log("val ", val); // This returns: undefined
var obj = {};
var temp = angular.element('div');
temp.innerHTML = val;
if (type === 'set') {
obj.value = val;
obj.value_filter = temp.textContent || temp.innerText;
console.log(obj.value_filter);
return;
} else if (type === 'filter') {
return val;
} else if (type === 'sort') {
return val;
}
return obj.value;
},
"sDefaultContent": '',
"aTargets": [ 1 ]
},
]
The issue is that val parameter inside mDataProp always returns undefined, so the table data population would error out, if not for the sDefaultContent property.
See this fiddle.
Why cannot the mDataProp get the val parameter populated? Does mDataProp support an array of arrays as data source? (The documentation is not clear about this)
After digging through a bit I found out that when mDataProp is used as a function, it does not have any reference to the data being passed to the datatable from the javascript array variable, thus returning undefined for val.
The workaround for this particular case is to use direct array position references in the source parameter, depending on the aTargets value to be used. (If using "aTargets": [ 1 ], then have to call source[1] in the mDataProp function).
I did not use if (type === "set"){}, 'cause I could not access it.
"mDataProp": function(source, type, val) {
var obj = {};
obj.value = source[1]; // Set column value
// Process value as desired ...
obj.value_filter = obj.value + ' foobar';
// Return value for filtering
if (type === 'filter') {
return obj.value_filter;
}
// Return original value for display, sort, etc.
return obj.value;
}
Click updated fiddle.

Reactive computed data in VueJs 2.0

I have a paginated record set from a http response and want to further implement client side pagination on return paginated record set, thus I have the following component markup
<td v-for="item in items">....</td> // only print 5 at a time
and in the default....
{
data: { return {
itemsData:[] // populated from RESTful data in increments of 20
, offset: 0 // for internal pagination
} },
computed: {
items: function(){
return this.itemsData.slice(this.offset, 5); // re-populate over time as offset changes
}
},
methods: {
getItems: function() {
this.$http.get('/api/items/?page=' + this.page).then(response=>
{
this.itemsData = response.data.data; // json array and I al get back meta data
// for which i use in a mixin to calculate offset and page etc.
// for both client side and server side pagination
}) // fetches records 20 at a time
}
}
.........
If itesmData is populated and then offset is dynamically changed. Shouldn't the component's template re-rendered with a new items collection?
Or should I be using a method instead? e.g.
<td v-for="item in paginated(itemData)">....</td>
{
....
methods: {
paginated: function(items){
var arr=[];
for( var i = this.offset; i < this.offset + 5; i++)
arr.push(item[i]);
return arr;
}
}
How would the template be updated with the new array? Would I need to implement a watcher? on the computed data? or would the offset do?
UPDATE:
I tried to implement the pagination via competed and while I get the template to render the first 5..... in trying to re-render after updating offset does not fire.... arr seems to return empty even thought i am on the second page and offset is yet to reach itemsData.length
Can you iterate through a data array property OUTSIDE of the template? i.e. loop through this.itemsData[i] or this.$data.itemsData[i]???
You need to make following changes in your code:
computed: {
items: function(){
return this.itemsData.slice(this.offset, this.offset + 5); // re-populate over time as offset changes
}
}
As you can see from documentation, slice takes two argument start and end, it will return a portion of an array into a new array object selected from start to end (end not included).

Error while trying to display content from a store

I am trying to display console.log(r.get('info')) but, i am getting the output as (an empty string). What might have caused this error ?
var myst = Ext.getStore('MyStore');
var r = myst.getAt(0);
myst.on('load', function() {
r = myst.getAt(0);
console.log(r);
console.log(r.get('info'));
});
UPDATE 1
MODEL
Ext.define('MyApp.model.MyModel', {
extend: 'Ext.data.Model',
fields: [
{
name: 'info'
}
]
});
UPDATE 2
I actually get Object { phantom=true, internalId="ext-record-18", raw={...}, more...} when i print console.log(r)'and inside raw, i see info:"myname".
To display array or objects try console.dir(object).

Dojo Tree : bridge from *unformatted* json to expected format

I am very new to Dojo (1.7), and I am very excited by the AMD loader and the global philosophy, then thought I have red some dozen of documentation and googled a lot and my brains starts to grill, I am still unable to understand and perform some things : I would like to display a dijit.Tree of any sort of JSON, yes like a JSON editor, because I use also persistent JSON files for storing few datas (not only for GET/.../ transmission) . Here are my expects :
sample JSON : {"infos":{"address":"my address","phone":"my
phone"},"insurance":{"forks":[14,53,123],"prices":[5,8,"3%"]}}
display the differents variables of any JSON : the root child is the
root json variable, children L1 are the root variables, etc...and upon the json variable type (String, Number, Object, Array) I will also display a corresponding icon
not to have to parse the whole json and format it in one big time, would like for exemple to display first the root node, then the well formated children trought a getChildren method for example, so it is done progressively on expando (like a lazy load). I have already made my own Trees classes with javascript, the more flexible way was I gave a dataRoot, a renderItem(dataItem, domItem) and a getChildren(dataItem) to the constructor so I could perform and return all I want, the Tree only performed the rendering only when needed, the Tree had no knowing about datas structure neither modify it, but I am not sure to understand well why the dijit.Tree needs a so restrictive way of build...
Here is my last try, it might totally not the right way, (maybe I have to subclass) but as far as I understand, I need to play with 3 classes (dojo store, tree model and tree widget), but firstly it seems the model can't get the root node, please check my different code comments. So please is there any patient person that can give me a simple example with some clear explanations (yeah I am a bit demanding), at least the list of the right necessary variables for constructor's options I need for start displaying a nice tree view of my json file, there's so much I'm totally lost, many thanks !
...
// before there is the AMD part that load the needed things
Xhr.get({ url:'data/file.json', handleAs:'json',
load: function(data){
console.log('xhr.loaded : ', data);// got my javascript object from the json string
var store = new ItemFileReadStore({// is it the right store I need ??
// or the Memory store ?
// assuming later I'll need to save the data changes
rootId : 'root',//
rootLabel : 'Archive',// useless ? isn't it the model responsability ?
data : {id:'root', items:[data]}// trying to give a root node well formatted
});
var model = new TreeStoreModel({
store : store,
getChildren : function(obj){
// firstly here it seems the root is not found
// I got a 'error loading root' error
// what is missing in my instanciations ??
// what is exactyly the type of the 1st arg : a store ?
console.log('getChildren : ', this.get(obj.id));
},
mayHaveChildren : function(){
console.log('mayHaveChildren ', arguments);
return true;
}
});
var tree = new Tree({
model: model
}, domId);
tree.startup();
}
});
My solution is based on dojo/store/Memory inspired by Connecting a Store to a Tree:
You can find live demo at http://egoworx.com/ or download complete source from dropbox.
Now code. First dojo/store/Memory:
var data = {"infos":{"address":"my address","phone":"my phone", "gift": false, "now": new Date()},"insurance":{"forks":[14,53,123],"prices":[5,8,"3%"]}};
var store = new Memory({
data: data,
mayHaveChildren: function(object) {
var type = this.getType(object);
return (type == "Object" || type == "Array");
},
getChildren: function(object, onComplete, onError) {
var item = this.getData(object);
var type = this.getType(object);
var children = [];
switch(type) {
case "Array":
children = item;
break;
case "Object":
for (i in item) {
children.push({label: i, data: item[i]});
}
break;
}
onComplete(children);
},
getRoot: function(onItem, onError) {
onItem(this.data);
},
getLabel: function(object) {
var label = object.label || object + "";
var type = this.getType(object);
switch(type) {
case "Number":
case "String":
case "Boolean":
case "Date":
var data = this.getData(object);
if (data != label) {
label += ": " + this.getData(object);
}
}
return label;
},
getData: function(object) {
if (object && (object.data || object.data === false) && object.label) {
return object.data;
}
return object;
},
getType: function(object) {
var item = this.getData(object);
if (lang.isObject(item)) {
if (lang.isArray(item)) return "Array";
if (lang.isFunction(item)) return "Function";
if (item instanceof Date) return "Date";
return "Object";
}
if (lang.isString(item)) return "String";
if (item === true || item === false) return "Boolean";
return "Number";
},
getIconClass: function(object, opened) {
return this.getType(object);
}
});
Please note I added a boolean and Date type to your data.
dijit/Tree based on this store:
var tree = new Tree({
model: store,
persist: false,
showRoot: false,
getIconClass: function(object, opened) {
if (lang.isFunction(this.model.getIconClass)) {
return this.model.getIconClass(object, opened);
}
return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf";
}
}, "placeholder");
tree.startup();
And finally a stylesheet to display data type icons:
.dijitTreeIcon {
width: 16px;
height: 16px;
}
.Object {
background-image: url(http://dojotoolkit.org/api/css/icons/16x16/object.png);
}
.Array {
background-image: url(http://dojotoolkit.org/api/css/icons/16x16/array.png);
}
.Date {
background-image: url(http://dojotoolkit.org/api/css/icons/16x16/date.png);
}
.Boolean {
background-image: url(http://dojotoolkit.org/api/css/icons/16x16/boolean.png);
}
.String {
background-image: url(http://dojotoolkit.org/api/css/icons/16x16/string.png);
}
.Number {
background-image: url(http://dojotoolkit.org/api/css/icons/16x16/number.png);
}
I cannot access jsFiddle since I'm currently in China, but I'll put the code above there upon my return to Europe and post a link here.
Try somethign like that instead :
store = new dojo.data.ItemFileWriteStore({
url : "",
data: {
identifier: "id",
label : "label",
items : [{
id : "root",
label : "root",
type : "root",
children: [data]
}]
}
});
Also in general avoid overriding the tree functions, you might extend them, but becareful.
If you want to console.log, then rather connect to them...
ItemFileReadStore is a read-only store, so not the one you want for "saving modifications".
You can try the ItemFileWriteStore, or JsonRest, etc.

Filtering epics from Kanban board

I would like to start by saying I have read Rally Kanban - hiding Epic Stories but I'm still having trouble on implementing my filter based on the filter process from the Estimation Board app. Currently I'm trying to add an items filter to my query object for my cardboard. The query object calls this._getItems to return an array of items to filter from. As far as I can tell the query calls the function, loads for a second or two, and then displays no results. Any input, suggestions, or alternative solutions are welcomed.
Here's my code
$that._redisplayBoard = function() {
that._getAndStorePrefData(displayBoard);
this._getItems = function(callback) {
//Build types based on checkbox selections
var queries = [];
queries.push({key:"HierarchicalRequirement",
type: "HierarchicalRequirement",
fetch: "Name,FormattedID,Owner,ObjectID,Rank,PlanEstimate,Children,Ready,Blocked",
order: "Rank"
});
function bucketItems(results) {
var items = [];
rally.forEach(queries, function(query) {
if (results[query.key]) {
rally.forEach(results[query.key], function(item) {
//exclude epic stories since estimates cannot be altered
if ((item._type !== 'HierarchicalRequirement') ||
(item._type === 'HierarchicalRequirement' && item.Children.length === 0)) {
items = items.concat(item);
}
});
}
});
callback(items);
}
rallyDataSource.findAll(queries, bucketItems);
};
function displayBoard() {
artifactTypes = [];
var cardboardConfig = {
types: [],
items: that._getItems,
attribute: kanbanField,
sortAscending: true,
maxCardsPerColumn: 200,
order: "Rank",
cardRenderer: KanbanCardRenderer,
cardOptions: {
showTaskCompletion: showTaskCompletion,
showAgeAfter: showAgeAfter
},
columnRenderer: KanbanColumnRenderer,
columns: columns,
fetch: "Name,FormattedID,Owner,ObjectID,Rank,Ready,Blocked,LastUpdateDate,Tags,State,Priority,StoryType,Children"
};
if (showTaskCompletion) {
cardboardConfig.fetch += ",Tasks";
}
if (hideLastColumnIfReleased) {
cardboardConfig.query = new rally.sdk.util.Query("Release = null").or(kanbanField + " != " + '"' + lastState + '"');
}
if (filterByTagsDropdown && filterByTagsDropdown.getDisplayedValue()) {
cardboardConfig.cardOptions.filterBy = { field: FILTER_FIELD, value: filterByTagsDropdown.getDisplayedValue() };
}
cardboardConfig.types.push("HierarchicalRequirement");
if (cardboard) {
cardboard.destroy();
}
artifactTypes = cardboardConfig.types;
cardboard = new rally.sdk.ui.CardBoard(cardboardConfig, rallyDataSource);
cardboard.addEventListener("preUpdate", that._onBeforeItemUpdated);
cardboard.addEventListener("onDataRetrieved", function(cardboard,args){ console.log(args.items); });
cardboard.display("kanbanBoard");
}
};
that.display = function(element) {
//Build app layout
this._createLayout(element);
//Redisplay the board
this._redisplayBoard();
};
};
Per Charles' hint in Rally Kanban - hiding Epic Stories
Here's how I approached this following Charles' hint for the Rally Catalog Kanban. First, modify the fetch statement inside the cardboardConfig so that it includes the Children collection, thusly:
fetch: "Name,FormattedID,Children,Owner,ObjectID,Rank,Ready,Blocked,LastUpdateDate,Tags,State"
Next, in between this statement:
cardboard.addEventListener("preUpdate", that._onBeforeItemUpdated);
And this statement:
cardboard.display("kanbanBoard");
Add the following event listener and callback:
cardboard.addEventListener("onDataRetrieved",
function(cardboard, args){
// Grab items hash
filteredItems = args.items;
// loop through hash keys (states)
for (var key in filteredItems) {
// Grab the workproducts objects (Stories, defects)
workproducts = filteredItems[key];
// Array to hold filtered results, childless work products
childlessWorkProducts = new Array();
// loop through 'em and filter for the childless
for (i=0;i<workproducts.length;i++) {
thisWorkProduct = workproducts[i];
// Check first if it's a User Story, since Defects don't have children
if (thisWorkProduct._type == "HierarchicalRequirement") {
if (thisWorkProduct.Children.length === 0 ) {
childlessWorkProducts.push(thisWorkProduct);
}
} else {
// If it's a Defect, it has no children so push it
childlessWorkProducts.push(thisWorkProduct);
}
}
filteredItems[key] = childlessWorkProducts;
}
// un-necessary call to cardboard.setItems() was here - removed
}
);
This callback should filter for only leaf-node items.
Mark's answer caused an obscure crash when cardboard.setItems(filteredItems) was called. However, since the filtering code is actually manipulating the actual references, it turns out that setItems() method is actually not needed. I pulled it out, and it now filters properly.
Not sure this is your problem but your cardboard config does not set the 'query' field. The fetch is the type of all data to retrieve if you want to filter it you add a "query:" value to the config object.
Something like :
var cardboardConfig = {
types: ["PortfolioItem", "HierarchicalRequirement", "Feature"],
attribute: dropdownAttribute,
fetch:"Name,FormattedID,Owner,ObjectID,ClassofService",
query : fullQuery,
cardRenderer: PriorityCardRenderer
};
Where fullQuery can be constructed using the the Rally query object. You find it by searching in the SDK. Hope that maybe helps.