PDA

View Full Version : [FIXED] Model Mapping throws unexpected error when mapping attribute with period (.) in name



michael.sterley
30 Aug 2012, 8:25 AM
Sencha Architect, throws an unexpected error exception, SyntaxError: Parse Error when mapping a well-formed Xml document that has a period (.) in the attribute name as bolded below.

<set>
<device id="123" name="TEST1" devid="12345678" org.id="4" deviceType.id="1">
<properties/>
</device>
</set>

aconran
30 Aug 2012, 9:01 AM
Could you give us an example project?

This is probably something we will have to take up with the Ext JS or Touch team. Perhaps, XmlReader needs something along the lines of JsonReader's useSimpleAccessors (http://docs.sencha.com/touch/2-0/#!/api/Ext.data.reader.Json-cfg-useSimpleAccessors).

michael.sterley
30 Aug 2012, 9:14 AM
Hi,

Try an type @org.id in the mapping field on the model field orgId, architect wil raise an exception, if you ignore it and try and run the app it will retain the value in the field and cause scripting errors when previewing the application.

Could you possibly think of any workarounds? If not that may just be the end of me using Architect and ExtJs as my our entire solution relies on a 3rd pary REST interface that has attributes named like this.

Michael

aconran
11 Sep 2012, 10:56 AM
This is a limitation/bug of the Ext JS data package. As you can see from the below code (generated within the framework, it tries to access @org.id as a property rather than quoting (and breaking it apart properly).



"var me = this
,fields = me.model.prototype.fields
,value
,internalId
,__field1 = fields.get("id")
,__field2 = fields.get("name")
,__field3 = fields.get("orgId")
;
return function(dest, source, record) {
value = source["@id"];
if (value === undefined) {
if (me.applyDefaults) {
dest["id"] = __field1.defaultValue
};
} else {
dest["id"] = value;
}; value = source["@name"];
if (value === undefined) {
if (me.applyDefaults) {
dest["name"] = __field2.defaultValue
};
} else {
dest["name"] = value;
};
value = source.@org.id;
if (value === undefined) {
if (me.applyDefaults) {
dest["orgId"] = __field3.defaultValue
};
} else {
dest["orgId"] = value;
};};"


A convert function cannot quite perform this behavior because it already assumes that it will be a child of the record. There is an unsupported/undocumented feature of mapping where you can pass in a function but I wouldn't advise going down that route. I'll try to get someone from the SDK team to chime in.

aconran
11 Sep 2012, 11:05 AM
Filed a ticket with the Ext JS team as EXTJSIV-7215.

Animal
11 Sep 2012, 11:36 AM
Any chance of an ExtJS testcase?

aconran
11 Sep 2012, 11:40 AM
Raw Ext JS Test case 38599

Animal
11 Sep 2012, 12:17 PM
Actually, it's OK, I tweaked the XML grid example to use an attribute name with a dot.

And yes, it doesn't work. I've escalated the priority of this so it will be fixed in the next release.

Animal
11 Sep 2012, 1:05 PM
OK, 2 things here.

First, the Model definition attempt to create a proxy and a reader with which it might read associations. This defaults to an Ajax Proxy and a Json Reader.

You will have to define your model:



Ext.define('Book',{
extend: 'Ext.data.Model',
proxy: {
type: 'ajax',
reader: 'xml'
},
fields: [
// whatever...
]
});


But even with that, there's a bug in DomQuery where it won't parse an attribute selector with a dot in it.

So I'll have to fix that.

Animal
11 Sep 2012, 1:18 PM
So with the above correction to the model definition, the workaround to the DomQuery bug is



Ext.dom.Query.matchers[4] = {
re: /^@([\w\-\.]+)/,
select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
}