Error When Ext.create(model with parameters) - extjs

When i try to compute this line
var project = Ext.create(CarboZero.model.Project,{strTitle: title ,strType: type ,strVersion: "1.0.0" ,dateEventDate: new Date() , arrCategory: "Energy"});
with this model definition
Ext.define('CarboZero.model.Project', {
extend: 'Ext.data.Model',
singleton: true,
config: {
fields: [
{
name: 'arrCategory'
},
{
name: 'strTitle'
},
{
name: 'dateEventDate'
},
{
name: 'strVersion'
},
{
name: 'strType'
}
]
}
});
It does not work and give me the error
Uncaught TypeError: Object [object Object] has no method 'substring'
Not quite sure what i do wrong, but im pretty sure its in the parameters has i normally write it that way and it works fine (without parameters).

You will get this kind of error if you had chose to make your model a Singleton.
Because Singleton are initialized at app startup and that you don't ever need to do it your self.

Related

Kendo DataSource reading from Async/await method which uses Axios to fetch data

Using React with TypeScript
Please could somebody provide an example of how I might be able to use a Kendo DataSource to read from a method which internally uses Axios to prod an external API for JSON data..? I must have flown through 20 different versions of this code trying different approaches, nothing seems to fit...
All I'm trying to do currently is supply a Kendo ComboBox with an array of {id: number, name: string}
Very basic stuff at the moment, but I do have to use a similar approach to this later on with a Kendo Grid which handles server side sorting and pagination so I'd like to get this working now then that should be somewhat easier later on...
The reason I want to use Axios is because I've written an api.ts file that appends appropriate headers on the gets and posts etc and also handles the errors nicely (i.e. when the auth is declined etc...)
A basic example of what I'm trying, which isn't working is this: -
public dataSource: any;
constructor(props: {}) {
super(props);
this.dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: function() {
return [{ id: 1, name: "Blah" }, { id: 2, name: "Thing" }];
}.bind(this)
},
schema: {
model: {
fields: {
id: { type: "number" },
name: { type: "string" }
}
}
}
});
}
<ComboBox
name="test"
dataSource={this.dataSource}
placeholder={this.placeholder}
dataValueField="id"
dataTextField="name"
/>
Anybody got any thoughts on this please? :)
Easy fix in the end...
this.dataSource = new kendo.data.DataSource({
transport: {
read: function(options: any) {
options.success([{ id: 1, name: "Blah" }, { id: 2, name: "Thing" }]);
}.bind(this)
},
schema: {
model: {
fields: {
id: { type: "number" },
name: { type: "string" }
}
}
}
});
2 things were wrong..
Removed the type: "odata",
and
Added the usage of options in
All working fine now with the async await function also, just passing the data into the options.success in the .then on the promise. Job done :-)

Restangular - How do I reach this API using GET method?

How do I make a GET call to a REST API with the below signature:
http://www.example.com/hierarchies/nodes/1005/parents
I am trying to call the API like so:
var service = Restangular.all('hierarchies');
return service.one('nodes', id).all('parents').get();
But it throws the following error:
TypeError: Cannot read property 'toString' of undefined
The API call(if successful) would respond in a nested format as below:
{
name: "",
children: [
{
name: "",
children: [
{
name: "",
children: [
..
]
}
]
}
]
}
Thanks in advance!
I think if you use all as the last part of the builder, a list is expected and you should use getList instead of get. However the object you are expecting does not look like a list, so you could change the last part of your builder to just use one without the second parameter and then a single object as the response will be expected.
service.one('nodes', 5).one('parents').get().then(function(response) {
});

Ember.js binding on array inside a property

Hello emberjs experts :)
There is something that i don't understand.
Given the following route:
Evibe.MemberShowRoute = Ember.Route.extend({
model: function(params) {
return Ember.$.getJSON('/api/user').then(function(user) {
return Ember.Object.create(user);
});
}
});
The call to the api simply returns a user object containing properties. One of this property is an array of picture objects. Like that:
{
username: "A nice user",
pictures: [
{id: 1, is_main: true, url: 'http://www.test.com/img1.jpg'},
{id: 2, is_main: false, url: 'http://www.test.com/img2.jpg'},
{id: 3, is_main: false, url: 'http://www.test.com/img3.jpg'},
{id: 4, is_main: false, url: 'http://www.test.com/img4.jpg'},
]
}
In my controller, i have something like this:
Evibe.MemberShowController = Ember.ObjectController.extend({
nb_pictures: function() {
return this.pictures.length;
}.property('pictures'),
addPictureObject: function(picture) {
this.get('pictures').addObject(picture);
}
});
And in my template, i have something like this:
{{ nb_pictures }} pictures
I don't understand why nb_pictures is not updated, as i'm adding an object into my "pictures" property with the addPictureObject function.
Also, when i try to do something like this:
this.get('pictures').setEach('is_main', false); // Works
this.get('pictures').findBy('id', pictureId).is_main = true; // Doesn't work
this.get('pictures').findBy('id', pictureId).set('is_main', true) // Doesn't work
The first line works as expected.
But... for the second line, i get the error: "Assertion failed: You must use Ember.set() to access this property (of [object Object])"
And for the third one, i get the error: "Uncaught TypeError: Object # has no method 'set' "
Any ideas that can help clarify this would be greatly appreciated.
In your nb_pictures computed property, you have set the dependent key with property('pictures'), the correct is property('pictures.length').
This is the updated code:
Evibe.MemberShowController = Ember.ObjectController.extend({
nb_pictures: function() {
return this.get('pictures.length');
}.property('pictures.length'),
addPictureObject: function(picture) {
this.get('pictures').addObject(picture);
}
});
Using just property('pictures') will make the framework observe just the array replacement, like set('pictures', [...]), not the changes in the array structure get('pictures').pushObject(...). this the reason that your ui don't update.

Dynamically add xtype items to the panel with slidenavigatoin

So I'm trying to put items dynamically to the panel that has slidenavigation feature:
// FlyoutNavigation.js
Ext.define("APN.view.FlyoutNavigation", {
id: "flyoutNavigationPanel",
extend: 'Ext.ux.slidenavigation.View',
Here is the initialisation of the view in another view:
// MainViewContainer.js
this.home = "Some var"
this.flyout = Ext.create('APN.view.FlyoutNavigation', {
id: 'flyoutNavigationPanel',
home: this.home
});
Than I'm trying to use this variable in the this.config.items section, however that doesn't work, it seems that Sencha compiles everything first and than initialiases the components, I might be wrong, I'm really new to Sencha Framework.
So here is the view where the home variable is used:
Ext.define("APN.view.FlyoutNavigation", {
id: "flyoutNavigationPanel",
extend: 'Ext.ux.slidenavigation.View',
xtype: 'flyoutnavigation',
requires: [
... heaps of things omitted ...
],
initialize: function () {
this.callParent();
this.setupDynamicItems();
},
config: {
items: [
{
itemId: 'nav_home',
id: 'homeView',
items: [{
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: this.home, // - that's the place where UNDEFINED occurs
flex: 1
}
],
},
So this.home is undefined...
One possible solution
Comming from this question: How to dynamically create xtype templates in Sencha Touch
I decided to put all the code in this.config.items.add({ ... my items ... }) however Ext.ux.slidenavigation.View looks like gave me the BUG! :( as the initialise method occurs after the binding methods on items of FlyoutNavigation view.
Here is the message from of the bug: Uncaught TypeError: Cannot read property 'raw' of undefined View.js:310 which is basically this line: if (Ext.isFunction(item.raw.handler)) {
So my questions would be
How to get the instance variable in the config.items section? If that's possible, than all is OK
Or do you know the work around of this issue?
Thanks
I don't think you can use this.config when defining the class, instead you can use initialize function as I told you earlier. So you should be able to do this:
initialize : function() {
var me = this;
var home = me.config.home;
me.add({
itemId: 'nav_home',
id: 'homeView',
items: [{
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: home,
flex: 1
}
],
});
}
OR if you have defined homeView in parent class, you can do this:
initialize : function() {
var me = this;
var home = me.config.home;
me.down('#homeView').add({
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: home,
flex: 1
});
}

How to populate an Ext.data.TreeStore without children or leaf information?

I have a service that returns an array of Things. A Thing simply has an id and a name.
I want to load these into an Ext.tree.Panel. For now, I've defined a data store that mimics a typical response from the service. You can play with a demo JSFiddle here.
Code included below as well:
Ext.define('Thing', {
extend: 'Ext.data.Model',
fields: ['id', 'name'],
});
var store = Ext.create('Ext.data.TreeStore', {
model: 'Thing',
// example service response (in reality, this would be JSON)
root: {
children: [
{
id: 1,
name: 'Thing 1',
},
{
id: 2,
name: 'Thing 2',
},
{
id: 3,
name: 'Thing 3',
},
],
},
listeners: {
append: function(thisNode, newChildNode, index, eOpts) {
if( !newChildNode.isRoot() ) {
newChildNode.set('text', newChildNode.get('name'));
}
},
},
});
Ext.create('Ext.tree.Panel', {
renderTo: Ext.getBody(),
store: store,
rootVisible: false,
});
As you can see, the service only returns a Thing's id and name, no tree node information like children or leaf, which is what an Ext.data.TreeStore normally expects.
I simply cannot change what the service returns as a response. I like that I can call the service and get a flat array of Things, without extraneous tree node information. There are many apps talking to this service that simply do not need such data, and I don't have permission from the powers-that-be to change it.
Unfortunately, without the children element defined for each Thing in the response, Ext raises the following error when I attempt to expand a node (you can produce this yourself in the JSFiddle):
Uncaught TypeError: Cannot call method 'indexOf' of undefined
So, my question is: how can I avoid having to send back children (or leaf) in my response and resolve this error? I'd simply like my Things to be loaded into the tree and to be expandable (yes, they can't be leaves).
Add those information by yourself!
Little example (You easily can try it in the console from your browser):
a = {b:23};
a.c = 25;
//a is now the same like {b:23, c:25}
In the afterRequest-method of the store you can for example do following:
proxy: {
type: 'ajax',
url: 'xxx',
listeners: {
exception: function(proxy, response, options) {
//error case
}
},
afterRequest: function(request, success) {
var resText = request.operation.response.responseText,
allThings = Ext.decode(resText), //Decodes (parses) a JSON string to an object
things = allThins.children, //Now we have an object an we can do what we want...
length = things.length;
for (var i = 0; i < length; i++) {
things[i].leaf = true;
things[i].expanded = true;
}
this.setRootNode(allThings);
}
}
This is just some pseudo-code, but it should work!
Set a debugger Statement (Link) and see what you are really getting back!
I hope this helps!
You might try iterating over your response store and creating children nodes.
Then append your children to your root node
store.each(function(rec) {
var childNode ;
//Create a new object and set it as a leaf node (leaf: true)
childNode = Ext.create('Model_Name', {
id: rec.data.id,
name: rec.data.name,
text : rec.data.name,
leaf : true,
});
// add/append this object to your root node
treepanel.getRootNode().appendChild(childNode );
});
Check this link for more details

Resources