I am trying to use the rootProperty value in a Sencha Touch 2 store to load some JSON I retrieved from the Foursquare Venues API and for the life of me I cannot get it to work.
According to the docs I should setup my rootProperty in dot notation to equal "response.venues" but it does not populate the list. I put the json in a separate file and removed the "response" and "venues" headers and it worked fine. There must be something blatantly obvious I'm missing here as I can't find a straight answer anywhere.
My model:
Ext.define('App.model.4SqVenue', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'name', id: 'id'}
]
}
});
My store:
Ext.define('App.store.4SqVenues', {
extend: 'Ext.data.Store',
requires: [
'App.model.4SqVenue'
],
config: {
model: 'App.model.4SqVenue',
storeId: '4SqVenuesStore',
proxy: {
type: 'jsonp',
url: 'foursquare venue request',
reader: {
type: 'json',
rootProperty: 'response.venues'
}
}
}
});
My view:
Ext.define('App.view.4SqVenues', {
extend: 'Ext.List',
xtype: '4SqVenuesCard',
requires: [
'App.store.4SqVenues'
],
config: {
fullscreen: true,
itemTpl: '{name}',
store: '4SqVenuesStore'
}
});
The response from the 4sq API:
{
"meta": {
"code": 200
},
"response": {
"venues": [
{
"id": "4a3ad368f964a52052a01fe3",
"name": "Four Peaks Brewing Company",
"contact": {
"phone": "4803039967",
"formattedPhone": "(480) 303-9967",
"twitter": "4PeaksBrewery"
},
"location": {
"address": "1340 E 8th St",
"crossStreet": "at Dorsey Ln.",
"lat": 33.4195052281187,
"lng": -111.91593825817108,
"distance": 1827,
"postalCode": "85281",
"city": "Tempe",
"state": "AZ",
"country": "United States"
},
"categories": [
{
"id": "4bf58dd8d48988d1d7941735",
"name": "Brewery",
"pluralName": "Breweries",
"shortName": "Brewery",
"icon": {
"prefix": "https://foursquare.com/img/categories/nightlife/brewery_",
"sizes": [
32,
44,
64,
88,
256
],
"name": ".png"
},
"primary": true
}
],
"verified": true,
"stats": {
"checkinsCount": 24513,
"usersCount": 8534,
"tipCount": 235
},
"url": "http://www.fourpeaks.com",
"likes": {
"count": 0,
"groups": []
},
"menu": {
"type": "foodAndBeverage",
"url": "https://foursquare.com/v/four-peaks-brewing-company/4a3ad368f964a52052a01fe3/menu",
"mobileUrl": "https://foursquare.com/v/4a3ad368f964a52052a01fe3/device_menu"
},
"specials": {
"count": 0,
"items": []
},
"hereNow": {
"count": 1,
"groups": [
{
"type": "others",
"name": "Other people here",
"count": 1,
"items": []
}
]
}
}
]
}
}
I have a very similar issue. Basically all is good if I load the json without the rootProperty defined. But once I define it things stop working (bad configuration error reported in Architect).
So the belwo works opnlu until I define the rootProperty as 'records'
{ "records" : [ { "artist" : "Champion",
"index" : 1,
"recordid" : "r00899659",
"trackname" : "1 To 2"
},
{ "artist" : "Champion",
"index" : 2,
"recordid" : "r00899668",
"trackname" : "Is Anybody There?"
}
.......
],
"rowcount" : 10,
"timestamp" : "1/07/2012 5:05:19 AM"
}
first, you have to wrap it in a function call as Per documentation for the response. Then you may have to use a convert function inside your model. Such as setting the root property to response, and then using convert to bring in all the other data from the venue property.
Related
We are currently using GA4 data API and faced the issue when custom dimensions returns value "(not set)".
We were using the following article to set custom dimension for the session count, but we still receiving "(not set)" values.
Example of request:
{
"dateRanges": [
{
"startDate": "2021-09-01",
"endDate": "2021-09-05"
}
],
"offset": 0,
"limit": 100,
"dimensionFilter": {
"filter": {
"fieldName": "eventName",
"stringFilter": {
"matchType": 1,
"value": "screen_view",
"caseSensitive": true
}
}
},
"dimensions": [
{
"name": "customUser:applicationID"
},
{
"name": "customEvent:ga_session_number"
},
{
"name": "dateHour"
},
{
"name": "platform"
},
{
"name": "sessionSource"
},
{
"name": "sessionMedium"
},
{
"name": "sessionCampaignName"
},
{
"name": "deviceCategory"
}
],
"metrics": [
{
"name": "userEngagementDuration"
}
]
}
Does anybody have any idea why it may happen?
Now suppose I have a json data formation like this following:
{
"ServiceName": "cacheWebApi",
"Description": "This is a CacheWebApiService",
"IsActive": true,
"Urls": [{ "ServiceAddress": "http://192.168.111.210:8200", "Weight": 5, "IsAvailable": true },
{ "ServiceAddress": ",http://192.168.111.210:8200", "Weight": 3, "IsAvailable": true }]
}
Now what worries me is that the "Urls" is another nested json formation. So how to bind this value to the datatables? And have you got any good ideas (e.g:something like I only wanna show all the ServiceAddress)...
This should do what you need:
var data = [{
"ServiceName": "cacheWebApi",
"Description": "This is a CacheWebApiService",
"IsActive": true,
"Urls": [
{
"ServiceAddress": "http://192.168.111.210:8200",
"Weight": 5,
"IsAvailable": true
},
{
"ServiceAddress": ",http://192.168.111.210:8200",
"Weight": 3,
"IsAvailable": true
}
]
}];
$(function() {
var table = $('#example').dataTable({
"data": data,
"columns": [
{
"data": "ServiceName"
}, {
"data": "Description"
}, {
"data": "IsActive"
}, {
"data": "Urls[0].ServiceAddress"
}, {
"data": "Urls[0].Weight"
}, {
"data": "Urls[0].IsAvailable"
}, {
"data": "Urls[1].ServiceAddress"
}, {
"data": "Urls[1].Weight"
}, {
"data": "Urls[1].IsAvailable"
}
],
});
});
You should put your data in an array though. Working JSFiddle
EDIT
IF the number of Urls isn't defined then you could do something like this:
var table = $('#example').dataTable({
"data": data,
"columns": [
{
"data": "ServiceName"
}, {
"data": "Description"
}, {
"data": "IsActive"
}, {
"data": "Urls",
"render": function(d){
return JSON.stringify(d);
}
}
],
});
I guess that that isn't brilliant but you could do almost anything to that function, for instance:
var table = $('#example').dataTable({
"data": data,
"columns": [
{
"data": "ServiceName"
}, {
"data": "Description"
}, {
"data": "IsActive"
}, {
"data": "Urls",
"render": function(d){
return d.map(function(c){
return c.ServiceAddress
}).join(", ");
}
}
],
});
I am working on a Sencha touch app. I made a jsonP request which returns an audio url, I will like to write a function that will play that audio on a button click.
The structure of the call and the response is as follows:
Ext.data.JsonP.request({
url: 'https://api.pearson.com/v2/dictionaries/entries',
callbackKey: 'callback',
params: {
apikey: 'ZzNOnelsRcNcE7Npoh2SdAeQbjRA4XE4',
headword: 'school'
}
// RESPONSE.....
{
"status": 200,
"offset": 0,
"limit": 2,
"count": 2,
"total": 245,
"url": "/v2/dictionaries/entries?headword=school&limit=2",
"results": [
{
"datasets": [
"ldoce5",
"dictionary"
],
"headword": "school",
"homnum": 1,
"id": "cqAFqfYHHt",
"part_of_speech": "noun",
"senses": [
{
"definition": "a place where children are taught",
"examples": [
{
"audio": [
{
"type": "example",
"url": "/v2/dictionaries/assets/ldoce/exa_pron/p008-001919005.mp3" // The audio url
}
],
"text": "His mother always used to pick him up from school."
}
],
"gramatical_info": {
"type": "uncountable and countable"
},
"signpost": "where children learn"
}
],
"url": "/v2/dictionaries/entries/cqAFqfYHHt"
},
{
"datasets": [
"wordwise",
"dictionary"
],
"headword": "school",
"id": "cqARFaW3Aw",
"part_of_speech": "noun",
"senses": [
{
"definition": "a place where children are taught, or the time they spend there every day",
"examples": [
{
"text": "Mr Mamood is a teacher at my school ."
}
]
}
],
"url": "/v2/dictionaries/entries/cqARFaW3Aw"
}
]
}
You could use a Ext.Audio component provided by Sencha Touch, hiding it.
{
id: 'audio',
xtype: 'audio',
hidden: true,
url: null
}
As soon as you get the audio url set it on the component:
Ext.getCmp('audio').setUrl(mp3Url);
Then you would use a button to toggle play/pause on it:
{
xtype: 'button',
text: 'Play'
handler: function() {
// get the audio component (using its id)
var audio = Ext.getCmp('audio');
audio.toggle();
this.setText(audio.isPlaying() ? 'Pause' : 'Play');
}
}
Check out http://docs.sencha.com/touch/2.3.1/#!/api/Ext.Audio for a working example.
I am fetching nested data to be shown as nested list but whenever I tap on top level item, it again shows same top level list instead of showing children list and a ajax request is fired to fetch json data again. Here is the store:
Ext.define('MyTabApp.store.CategoriesStore',{
extend:'Ext.data.TreeStore',
config:{
model : 'MyTabApp.model.Category',
autoLoad: false,
storeId : 'categoriesStore',
proxy: {
type: 'ajax',
url: 'resources/data/catTree.json',
reader: {
type: 'json',
rootProperty: 'data.categories'
}
},
listeners:{
load: function( me, records, successful, operation, eOpts ){
console.log("categories tree loaded");
console.log(records);
}
}
}
});
and here is the data in that file which I am using to mock service:
{
"data":{
"categories": [
{
"name": "Men",
"categories": [
{
"name": "Footwear",
"categories": [
{ "name": "Casual Shoes", "leaf": true },
{ "name": "Sports Shoes", "leaf": true }
]
},
{
"name": "Clothing",
"categories": [
{ "name": "Casual Shirts", "leaf": true },
{ "name": "Ethnic", "leaf": true }
]
},
{ "name": "Accessories", "leaf": true }
]
},
{
"name": "Women",
"categories": [
{ "name": "Footwear", "leaf": true },
{ "name": "Clothing", "leaf": true },
{ "name": "Accessories", "leaf": true }
]
},
{
"name": "Kids",
"categories": [
{
"name": "Footwear",
"categories": [
{ "name": "Casual Shoes", "leaf": true },
{ "name": "Sports Shoes", "leaf": true }
]
},
{ "name": "Clothing", "leaf": true }
]
}
]
}
}
This is the list:
Ext.define('MyTabApp.view.CategoriesList', {
extend: 'Ext.dataview.NestedList',
alias : 'widget.categorieslist',
config: {
height : '100%',
title : 'Categories',
displayField : 'name',
useTitleAsBackText : true,
style : 'background-color:#999 !important; font-size:75%',
styleHtmlContent : true,
listConfig: {
itemHeight: 47,
itemTpl : '<div class="nestedlist-item"><div>{name}</div></div>',
height : "100%"
}
},
initialize : function() {
this.callParent();
var me = this;
var catStore = Ext.create('MyTabApp.store.CategoriesStore');
catStore.load();
me.setStore(catStore);
}
});
The list starts working properly without any ajax request on each tap if I remove data wrapper over top categories array and change rootProperty to categories instead of data.categories. Since server is actually returning categories in data object I cannot remove it so how do I fix the store in that case? Also why is that additional ajax request to fetch the file?
[EDIT]
Tried to create a fiddle http://www.senchafiddle.com/#d16kl which is similar but not same because it is using 2.0.1 and data is not loaded from external file or server.
Last time I had this exact situation, it was because one of my top level category was a leaf but I had not set leaf:true. Doing so recalled the top level of the nested list as if it was a child.
It seems from your Fiddle that if your data is in this following format, it would work fine:
{
"categories" : [{
"name" : "Foo",
"categories" : [{
...
}]
}]
}
That is, just remove the "data" property and make defaultRootProperty: 'categories' & rootProperty: 'categories'. Check this: http://www.senchafiddle.com/#d16kl#tIhTp
It works with external data file as well.
I would like to be able to maintain different stores from the same json where the model for each store is the same. Each store would need to be updated based on its root property assignment. Please see below for a sample json, store, and model, in which case each store would be updated based on the json's root property value (category 1, category 2, etc.). The goal is to be able to bind a nested list in my application to different stores on the fly, rather than call setProxy to change the url setting on a single store. Also, the json needs to be in this format. Thanks for your help and please let me know if I can provide clarification or answer any questions.
Json:
{
"items": [
{
"name": "category 1",
"status": "",
"displaytext": "",
"items": [
{
"name": "",
"status": "",
"displaytext": "",
"items": [
{
"name": "",
"status": "",
"displaytext": "",
"items": [
{
"name": "",
"status": "",
"displaytext": "",
"leaf": true
}
]
}
]
}
]
},
{
"name": "category 2",
"status": "",
"displaytext": "",
"items": [
{
"name": "",
"status": "",
"displaytext": "",
"items": [
{
"name": "",
"status": "",
"displaytext": "",
"leaf": true
}
]
}
]
},
{
"name": "cateory 3",
"status": "",
"displaytext": "",
"items": []
},
{
"name": "category 4",
"status": "",
"displaytext": "",
"items": []
}
]
}
Model:
Ext.define('MyApp.model.myModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'name',
type: 'string'
},
{
name: 'status',
type: 'string'
},
{
name: 'displaytext',
type: 'string'
}
]
}
});
Store 1, 2, 3, etc:
Ext.define('MyApp.store.storeCategory1', {
extend: 'Ext.data.TreeStore',
requires: [
'MyApp.model.myModel'
],
config: {
model: 'MyApp.model.myModel',
storeId: 'myStore',
autoLoad: false,
proxy: {
type: 'ajax',
url: '/path/to/file.json',
reader: {
type: 'json',
rootProperty: 'items'
}
}
}
});
I think you best bet would be to make a server request independent of the Store's proxy. On success, split up the data into the different stores as needed. It's fine to preprocess data this way, especially if you need to split one large data response into multiple data stores. For example:
Ext.Ajax.request({
url: 'path/to/file.json',
success: function(response){
// process server response here
var json = Ext.decode(response.responseText);
for(var i=0, l=json.items.length, i<l; i++){
// start distributing the data to your different stores here
}
}
});
Hope this helps.