Related
I'm programming a function in order to update users' info. I did it and it works fine however it doesn't work when I want to use custom schemas. I checked the reference but it showed an error "Invalid Input: [employmentData] "
function directoryUpdate(userId, userDept, userLocation, userPhone,userTitle) {
var userId = 'devtest#pruebatest.com',userDept='D003', userLocation='L003';
var userTitle='T003';
var update = {
ims:
[{
type: "work",
protocol: "gtalk",
im: "liz_im#talk.example.com",
primary: true
}],
emails: [
{
address: "liz#example.com",
type: "home",
customType: "",
primary: true
}
],
addresses:
[{
type: "home",
customType: "",
streetAddress: "1600 Amphitheatre Parkway",
locality: "Mountain View",
region: "CA",
postalCode: "94043"
}
],
organizations:
[{
name: "Next Step",
title: userTitle,
primary: true,
type: "work",
department: userDept,
location: userLocation
}],
customSchemas: {
employmentData: {
employeeNumber: "123456789",
jobFamily: "Engineering",
location: "Atlanta",
jobLevel: 8,
projects: [
{ value: "GeneGnome", customType: "development" },
{ value: "Panopticon", customType: "support" }
]
}
}
};
update = AdminDirectory.Users.patch(update, userId);
Logger.log('User %s updated with result %s.', userId, update)
return true;
}
What's the error?
Greetings, Thanks in advance.
The employmentData field is inside the "customSchemas" field. Custom schemas have to be defined before using them.
To create a Custom Schema you have to use the resource Schemas.insert.
After creating the schema with the correspondent fields and type of value (STRING, INT, ETC) your code should run without issues. I tried it and worked for me.
Also, after updating the user, when making the call to Users.get, you have to set the parameter "projection=full" in order to see these values in the response.
I have JSON with structure like this:
"id":1,
"user_role":"ADMIN",
"state":"ACTIVE",
"address":{
"street":"test 59",
"city":"City test",
"post_number":"25050"
},
How I should to pass values of address.street into column using setting in fields and model?
Many thanks for any advice.
If you want to show all values in a single column do what #RobinGiltner suggests.
If you want to show each member of address in a different column you can do:
var grid = $("#grid").kendoGrid({
dataSource: data,
editable: true,
columns : [
{ field: "id", title: "#" },
{ field: "user_role", title: "Role" },
{ field: "address.street", title: "Street" },
{ field: "address.city", title: "City" },
{ field: "address.post_number", title: "Post#" }
]
}).data("kendoGrid");
i.e.: use address.street as name of the field. This would allow you even to edit the field as in the example: http://jsfiddle.net/OnaBai/L6LwW/
#OnaBai Good and intuitive answer. Sadly Kendo doesn't always work to well with nested properties this way. For example formating doesn't work. Here is an example using data source shema to access nested properties. This way you can use formatting but you have to specify a schema model.
var grid = $("#grid").kendoGrid({
dataSource: {
data: data,
schema: {
model: {
id: "id",
fields: {
id: { type: "number" },
user_role: { type: "string" },
address_street: { from: "address.street" },
address_city: { from: "address.city" },
address_post_number: {
type: "number",
from: "address.post_number"
}
}
}
}
},
columns: [{
field: "id",
title: "#"
}, {
field: "user_role",
title: "Role"
}, {
field: "address_street",
title: "Street"
}, {
field: "address_city",
title: "City"
}, {
field: "address_post_number",
title: "Post#",
format: "{0:0#######}"
}]
}).data("kendoGrid");
Jsfiddle: http://jsfiddle.net/wtj6mtz2
See also this Telerik example for accessing nested properties.
You could use a template on the grid column definition to display whichever pieces of the address you wanted.
{ field: 'address', title: 'Address', template: '#= address.street# #= address.city#, #= address.post_number# ' },
See documentation for kendo column template. http://docs.telerik.com/kendo-ui/api/web/grid#configuration-columns.template
See sample at http://jsbin.com/gizab/1/edit
i have a json in the following format:
{
"collection": [
{
"id": 4,
"tickets": {
"collection": [
{
"inner_id": 8,
},
{
"inner_id": 10,
}
],
"count": 2,
"type": "collection"
},
},
{
"id": 5,
"tickets": {
"collection": [
{
"inner_id": 1,
},
{
"inner_id": 2,
}
],
"count": 2,
"type": "collection"
},
},
]
}
For this particular JSON i created the models as:
Ext.define("myProject.model.ABC", {
extend: "Ext.data.Model",
config: {
idProperty: "id",
fields:[
{name: "id", type: "int" },
],
hasMany: [
{
model: "myProject.model.XYZ",
name: "tickets",
associationKey: "tickets",
},
],
}
});
And second store as:
Ext.define("myProject.model.XYZ", {
extend: "Ext.data.Model",
config: {
// idProperty: "id",
fields:[
{name: "inner_id", type: "int" },
],
belongsTo: 'myProject.model.ABC'
}
});
But now i am confused. How do i populate the second store with a root property of collection again.
I know one way is to easily change the json so that there is no collection child inside tickets but i dont want to do that.
Any help would be appreciated. I have simplified the JSON for an easy example.
EDIT:
To be more clear, is there a way i can directly create a model which will read the Collection array inside the tickets object.
EDIT:
Adding the store which populates the model ABC for more understanding
Ext.define("myProject.store.ABCs", {
extend: "Ext.data.Store",
config: {
model: "myProject.model.ABC",
autoLoad: false,
proxy: {
type: "ajax",
url: '', //myURL
reader: {
type: "json",
rootProperty: "collection", // this is the first collection
},
},
}
});
This store loads the ABC model correctly but now i want to load the XYZ model which can load the inner array of collection
belongsTo should be define as follows :
Ext.define('Product', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'category_id', type: 'int' },
{ name: 'name', type: 'string' }
],
associations: [
{ type: 'belongsTo', model: 'Category' }
]
Have you read the doc? They specified the root property.
The name of the property which contains the data items corresponding to the Model(s) for which this Reader is configured. For JSON reader it's a property name (or a dot-separated list of property names if the root is nested). For XML reader it's a CSS selector. For Array reader the root is not applicable since the data is assumed to be a single-level array of arrays.
By default the natural root of the data will be used: the root JSON array, the root XML element, or the array.
The data packet value for this property should be an empty array to clear the data or show no data.
Sometimes the JSON structure is even more complicated. Document databases like CouchDB often provide metadata around each record inside a nested structure like this:
{
"total": 122,
"offset": 0,
"users": [
{
"id": "ed-spencer-1",
"value": 1,
"user": {
"id": 1,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}
}
]
}
In the case above the record data is nested an additional level inside the "users" array as each "user" item has additional metadata surrounding it ('id' and 'value' in this case). To parse data out of each "user" item in the JSON above we need to specify the record configuration like this:
reader: {
type : 'json',
root : 'users',
record: 'user'
}
root as a Function
reader: {
type : 'json',
root : function (obj) {
// I can't reproduce your problem
// so you should check in your console collection.id is right
return obj.collection.id
}
}
// Or, we can use dot notation
reader: {
type : 'json',
root : collection[0].tickets.collection
}
There are two ways to solve this problem. After researching extensively, i found two solutions...
SOLUTION 1:
Instead of making a second model, just create one model and create an array field with type as "auto"
Ext.define("myProject.model.ABC", {
extend: "Ext.data.Model",
config: {
idProperty: "id",
fields:[
{name: "id", type: "int" },
{ name: "tickets", convert: function(value, record) {
if(value.collection instanceof Array) {
return value.collection;
} else {
return [value.collection]; // Convert to an Array
}
return value.collection;
}
}
],
}
});
Now you can refer to an array of tickets from records by:
record.get('tickets')
SOLUTION 2:
Create three model instead of two.
Model 1:
hasOne Association with Tickets
Model 2:
hasMany association with Collection
Model 3:
has all the fields of the innermost array
I can give an example if its not clear enough
I've started creating a Sencha Touch 2 app that has two models defined, Change and Configuration. A Change belongsTo a Configuration. Both of the models also have a store setup. On the Changes store I have a proxy setup to request data that comes back in JSON format. The JSON data has a Change with a nested configuration. The Change loads just fine but when I try and get the associated Configuration from the Change instance it isn't working.
I've defined the models like this:
Change model:
Ext.define('Changes.model.Change', {
extend: 'Ext.data.Model',
xtype: 'changemodel',
config: {
fields: [
{name:'id', type:'int'},
{name:'changeId', type:'string'},
{name:'briefDescription', type:'string'},
{name:'configuration_id', type:'int'}
],
associations: [{
type:'belongsTo',
model:'Changes.model.Configuration',
primaryKey: 'id',
foreignKey: 'configuration_id',
associationKey: 'configurations'
}],
},
});
Configuration Model:
Ext.define('Changes.model.Configuration', {
extend: 'Ext.data.Model',
xtype: 'configurationmodel',
config: {
fields: [
{ name: 'id', type: 'int'},
{ name: 'longName', type: 'string' },
{ name: 'ciName', type: 'string' },
],
hasMany: {model: 'Change', name: 'changes'}
}
});
Each model has a store.
Changes store:
Ext.define('Changes.store.Changes', {
extend: 'Ext.data.Store',
requires: 'Changes.model.Change',
config: {
model: 'Changes.model.Change',
proxy: {
type: 'ajax',
url: 'services/changes.php',
reader: {
type: 'json',
rootProperty: 'changes'
}
},
sorters: [{ property: 'briefDescription', direction: 'ASC'}],
}
});
Configurations store:
Ext.define('Changes.store.Configurations', {
extend: 'Ext.data.Store',
requires: ['Ext.data.proxy.LocalStorage'],
config: {
model: 'Changes.model.Configuration',
grouper: {
sortProperty: "ciName",
direction: "DESC",
groupFn: function (record) {
return record.get('ciName')[0];
}
},
proxy: {
type: 'ajax',
url: 'services/configurationItems.php',
reader: {
type: 'json',
rootProperty: 'configurationItems'
}
}
}
});
My JSON that is being returned from services/changes.php looks like this:
{
"success": true,
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy",
"configuration_id": 3,
"configurations": [
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop"
}
]
}
]
}
In the browser's console I can issue the following commands:
Changes.myStore = Ext.getStore('Changes');
Changes.myStore.load();
Changes.record = Changes.myStore.findRecord('id', '1');
Changes.record.getAssociatedData()
The last command will return an object with a Configuration object inside but all of the field values show null except for id which appears to be set to a random value:
Object
Configuration: Object
ciName: null
id: "ext-record-11"
longName: null
Can anyone see why the nested Configuration instance in my JSON isn't being saved? And should the nested Configuration instance in the JSON be added to the Configurations store automatically?
Sadly this just doesn't work. Appears to be a shortcoming of the framework. You can't load and save associated (aggregated/nested) objects. You need to flatten out your structure and then associate objects in code yourself.
So for example... your JSON would then be...
{
"success": true,
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy"
}
]
}
And a second JSON file/response as follows:
{
"success": true,
"configurations": [
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop",
"change_id": 1
}
]
}
Tinashe's answer is not correct. You can certainly get nested models.
You have your associations backward with respect to your JSON, however.
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy",
"configuration_id": 3,
"configurations": [
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop"
}
]
}
]
means a change hasMany configurations, but you are saying it belongsTo it. This is the correct JSON:
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy",
"configuration_id": 3,
"configuration":
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop"
}
}
]
Either way, you need to set getterName (setterName if you like too) on the relationship:
associations: [{
type:'belongsTo',
model:'Changes.model.Configuration',
primaryKey: 'id',
foreignKey: 'configuration_id',
associationKey: 'configuration',
getterName:'getConfiguration'
}]
Then after the store loads, you can call myChangeModel.getConfiguration();
I am not able retrieve records from complex json objects but i am able to get the data when using an TPL.
Please see the below example codes:
JSON:
{
"lists": [
{
"title": "Groceries",
"id": "1",
"items": [
{
"text": "contact solution - COUPON",
"listId": "1",
"id": "4",
"leaf": "true"
},
{
"text": "Falafel (bulk)",
"listId": "1",
"id": "161",
"leaf": "true"
},
{
"text": "brita filters",
"listId": "1",
"id": "166",
"leaf": "false"
}
]
}
]
Model:
Ext.regModel("TopModel",
{
fields: [
{ name: 'title', type: 'string' },
{ name: 'id', type: 'string' },
],
hasMany: [
{ model: 'SubModel', name: 'items' }
],
proxy: {
type: 'ajax',
url : 'test/lists.json',
actionMethods: {
create: 'POST',
destroy: 'POST',
read: 'POST',
update: 'POST'
},
reader: {
type: 'json',
root: function(data) {
return data.lists || [];
}
}
}
});
Ext.regModel("SubModel",
{
fields: [
{ name: 'text', type: 'string'},
{ name: 'listId', type: 'string'},
{ name: 'id', type: 'string'},
{ name: 'leaf', type: 'string'}
]
});
In my View file, i have defined the store as below.
this.stores = new Ext.data.Store({
clearOnPageLoad: false,
autoLoad:true,
model:'TopModel',
getGroupString: function(record) {
return record.get('leaf');
}
});
});
I am not able to retrieve the values for record.get('leaf') as this refers to the child model items. When I tried to print it, it prints as undefined.
How to access the child attributes? Here 'items' is listed as an array.
I tried to display the data using list as below. All the records are displayed but the problem is that it is picked as one whole item instead of separate list for each item.
var list = new Ext.List({
cls: 'big-list',
grouped : true,
emptyText: '<div>No data found</div>',
itemTpl: ['<div><tpl for="items">',
'<div>',
'{id} {text}',
'</div>',
'</tpl></div>',
],
store: this.stores,
listeners: {
itemtap: this.onListItemTap,
scope: this
}
});
Kindly help me on how to get the list items to be displayed as individual records.
you can use online json parser(http://json.parser.online.fr/) to parse json xml from parser data you easily seprate objects and arrays and you get all data which are require for you..i hope this help you