"Cannot convert undefined or null to object" when click selected kendo tree item - angularjs

I used Kendo-angular directive for Kendo tree view. I formed datasource using the following method and view as below. I don't get any error if use Jquery style instead of Angular directive.
var dataSource = new kendo.data.HierarchicalDataSource()
$scope.templateData = dataSource ;
<div kendo-tree-view="tree" k-data-source="templateData" k-on-change="onTemplateSelection(dataItem)"></div>
$("#treeview").kendoTreeView({
spriteCssClass: "sprite",
dataSource: dataSource,
dataTextField: [ "AppName", "Name" ],
select: onSelect
});
Tree loads fine and on-change event fires when we click any item on tree. However, when we click the selected item again then change event doesn't trigger and it triggers error that reads.
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at Object.ve.proxyModelSetters (kendo.all.min.js:26)
at init.<anonymous> (kendo.all.min.js:86)
at init.trigger (kendo.all.min.js:25)
at init.select (kendo.all.min.js:59)
at init._click (kendo.all.min.js:58)

It's hard to find the error without having all the code but basically the exception you're getting is quite simple. Somewhere in your code you probably have a block that looks like this:
if (object !== "null") { // The null is a string and not actually null
...
Object.keys(object) ...
...
}
Search your code for 'null' or "null". if you don't find it like this, see if you might have misspelled it as well.

I found the mistake. Once I clicked an item on the tree, I used to remove the class, k-"state-selected" from the item. Next time when I click the same item, it seems it uses the same class("k-state-selected") and data-uid to find the selected item. So as it was not present on that item, it used to give the error mentioned above.

Related

EXTJS store related error when switching tabs: ext-all-debug.js:53117 Uncaught TypeError: Cannot read property 'isSynchronous' of null

I have a simplified fiddle that shows the issue I'm seeing:
https://fiddle.sencha.com/#view/editor&fiddle/2nbs
The application has two tabs. Each tab contains an instance of a component made up of a tree panel and a grid. Clicking a node in the tree populates the grid. If you visit both tabs before clicking a node in either tree then the application behaves. However, if you click a tree node in the first tab and thus populate the grid, then visiting the 2nd tabs throws this error:
ext-all-debug.js:53117 Uncaught TypeError: Cannot read property 'isSynchronous' of null
at constructor.loadsSynchronously (ext-all-debug.js:53117)
at constructor.createMask (ext-all-debug.js:106694)
at constructor.onRender (ext-all-debug.js:105766)
at constructor.finishRender (ext-all-debug.js:38449)
at constructor.finishRenderItems (ext-all-debug.js:76675)
at constructor.finishRender (ext-all-debug.js:76992)
at constructor.finishRenderChildren (ext-all-debug.js:79000)
at constructor.afterRender (ext-all-debug.js:37909)
at constructor.finishRender (ext-all-debug.js:38463)
at constructor.finishRenderItems (ext-all-debug.js:76675)
I'm building in extjs 5.1.3, but this reproduces in the latest version (6.6). I suspect I'm missing something stupidly obvious...
I found the problem...
the code that was destroying the old store was also destroying ext-store-empty - used by all empty grids etc
so I did this:
if (oldStore && oldStore.storeId !== 'ext-empty-store') {
oldStore.destroy();
}
there might be a neater way, but this works.

unable to update controller model value from custom directive with controller as syntax

I am facing problem to update my model values from custom directive using controller as syntax. I can clearly see that through console.log that the values are getting changed in the directive however they are not getting updated in the controller. <h4>{{self.tabs}} </h4> always shows same values.
In addition I want to do watch on controller (self --> tabs) model to add 'active class' but when I try to use watch it is throwing me out error. So I have commented that part. The following is the watch related code, which is not working:
$scope.$watch('tabsCtrlself.tabs.index', function() {
if (tabsCtrlself.tabs.index === index) {
angular.element($element).addClass('active');
}
});
Please find my plunker, Can any one direct me to fix this?
you can use 'ng-class' attribute,eg:
<en-tab data-pane="myPaneName1" ng-class="{active:index==1}">Tab #1</en-tab>
<en-tab data-pane="myPaneName2" ng-class="{active:index==2}" >Tab #2</en-tab>
<en-tab data-pane="myPaneName3" ng-class="{active:index==3}">Tab #3</en-tab>
'index' is a object in angular: $scope.index, initializes its value:
$scope.index=1;
The first item is selected by default.
I think the object of 'tabsCtrl.tabs.index' is not a angular object, so can't auto refresh

Adding listener to Ext.Grid.panel in EXTJS 4

I am trying to add a listener to a Ext.grid.panel
listeners: {
itemclick:function( grid, record, item, index, event){
alert(index);
var record = grid.getStore().getAt(index);
alert("Edit " + record.get('data'));
alert("Type " + record.get('type'));
}
I suppose to get the index value of the row I clicked. So when I click the row for the first time I get : [object Object] in the alert box with index in it. The second two alerts don't appear at all.
So when I again click the same row. it shows the correct index and then "data" and then " type" in an alert box.
How can I get the right values on the first click only?
When I add your listener to a grid panel of my own, I get the same behavior every time. For example:
4/"Edit undefined"/"Type undefined".
That you are seeing different behaviors depending on if it is the first time you click an item or not likely has something to do with how the grid is created/rendered.
The content of the Object passed as "index" to your listener function might give you a clue. If you log it to the console you'll be able to inspect it. (At least that's how Chrome handles logging of objects).
While this is not a solution to your problem, I hope it helps in your debugging.

Backbone per instance event bindings

I have a view that creates a sub-view per item in the list. Generically let's call them ListView and ListItemView. I have attached an event as follows on ListItemView:
events: {
"click .remove": "removeItem"
}
I have template-generated html for ListItemView that is approximately like the following (swapped lb/rb for {/} so you can see the "illegal" html):
{div class="entry" data-id="this_list_item_id"}
SOME STUFF HERE
{div class="meta"}
{a class="remove" href="javascript:;"}[x]{/a}
{/div}
{/div}
The problem is, when the click on any of the [x]'s, ALL of the ListItemViews trigger their removeItem function. If I have it go off of this model's id, then I drop all the items on the page. If I have it go off the clicked item's parent's parent element to grab the data-id, I get a delete for EACH ListItemView instance. Is there a way to create an instance-specific event that would only trigger a single removeItem?
If I have ListView hold a single instance of ListItemView and reassign the ListItem model and render for each item in the list it works. I only end up with one action (removeItem) being triggered. The problem is, I have to find the click target's parent's parent to find the data-id attr. Personally, I think the below snippet is rather ugly and want a better way.
var that = $($(el.target).parent()).parent();
Any help anyone gives will be greatly appreciated.
It seems like your events hash is on your ListView.
If it is, then you can move the events hash to ListItemView and your removeItem function can be the following
removeItem: function() {
this.model.collection.remove(this.model);
}
If this isn't the case, can you provide your ListView and ListItemView code so I can look at it.
A wild guess but possible; check that your rendered html is valid. It might be possible that the dom is getting in a tiz due to malformed html

Adding listener to an editor grid panel

There is an Editor grid panel.
I am trying to add a listener to the cell click event. I have tried to do it in different ways:
gridPanel.addListener('cellclick',myfunction);
inside the grid:
listeners: {
cellclick: myfunction
}
I have tried to do it in the selectionModel object.
None of them worked.
Where can be the problem?
If you can't add the listener as a config parameter, it's probably because you're having problems with the callback function not being in scope, similar to this:
> var obj = { greetMe: this.sayHi, sayHi: function(){ console.log('hi'); }};
undefined
> obj.greetMe();
TypeError: Property 'greetMe' of object #<Object> is not a function
> obj.greetMe
undefined
In the first line, this was still referring to the global (read: window) object at the time the object was defined. So this.sayHi === window.sayHi === undefined. The same thing happens when you define Ext config objects. Try defining the callback inline:
> var obj = { greetMe: function(){ console.log('hi'); }};
undefined
> obj.greetMe()
hi
Other options:
Define the function in a wider scope, outside of your class
Attach the listener within the constructor or within initComponent, by which time your class methods should be instantiated
Attach the listener sometime later
You have to use cellmousedown of grid panel or cell selectionchange of selection model.
addListener worked. I had some syntax error.
Still adding the listener as a parameter doesn't work
For row selection I put it on the selection model and for double clicks on the grid directly. This works well but I must warn you if you don't prevent the default event you will get horrible memory consumption.
Ext.onReady(function(){
requestGrid.getSelectionModel().on('rowselect', handleRowSelect);
requestGrid.on('rowdblclick', handleDoubleClick);
}
It would help if I read :) My solution is for row selection not cell selection but it might very well work.

Resources