UI-bootstrap: Cannot read property 'remove' of null - javascript

I'm using ui-bootstrap(accordion) for angular.
Also im creating recursive templates with directives to display nested object structure smthng like this:
[
{
name: String("Name1"),
key: String("name1"),
value: String("some text")
},
{
name: String("Name2"),
key: String("name2"),
value: {[
{
name: String("Object1"),
key: String("object1"),
value: {[
{
name: String("Object1 Name3"),
key: String("object1.name3"),
value: Object()
},
]}
},
{
name: String("Name4"),
key: String("name4"),
value: String()
},
]}
},
{
name: String("Name5"),
key: String("name5"),
value: Number("44")
}
]
To make displaying of complex object structure possible I used directive with recursive template and its works fine.
Also I have two buttons: "Edit" - makes possible edit values and "Cancel" - turns all input fields to disable mode.
When I'm pressing "Cancel" button I got this exception:
TypeError: Cannot read property 'remove' of null
at onDestroyTooltip (http://localhost:8080/js/lib/angularjs/ui-bootstrap-tpls-0.5.0.js?8b58789:2248:20)
at Scope.$broadcast (http://localhost:8080/js/lib/angularjs/angular.js?8b58789:12691:28)
at Scope.$destroy (http://localhost:8080/js/lib/angularjs/angular.js?8b58789:12349:14)
at HTMLDivElement.<anonymous> (http://localhost:8080/js/lib/angularjs/angular.js?8b58789:1017:18)
at HTMLDivElement.jQuery.event.dispatch (http://localhost:8080/js/lib/jquery/jquery.js?8b58789:3332:58)
at HTMLDivElement.elemData.handle.eventHandle (http://localhost:8080/js/lib/jquery/jquery.js?8b58789:2941:81)
at Object.jQuery.event.trigger (http://localhost:8080/js/lib/jquery/jquery.js?8b58789:3210:40)
at jQuery.fn.extend.triggerHandler (http://localhost:8080/js/lib/jquery/jquery.js?8b58789:3874:45)
at removePatch [as remove] (http://localhost:8080/js/lib/angularjs/angular.js?8b58789:2213:21)
at Object.leave (http://localhost:8080/js/lib/angularjs/angular.js?8b58789:4143:17)
Line: onDestroyTooltip (http://localhost:8080/js/lib/angularjs/ui-bootstrap-tpls-0.5.0.js?8b58789:2248:20) in stacktrace points to this part of ui-bootsrap code:
scope.$on('$destroy', function onDestroyTooltip() {
$timeout.cancel( transitionTimeout );
$timeout.cancel( popupTimeout );
unregisterTriggers();
tooltip.remove(); // <-- ERROR here!!!!!!!!!!!!!
tooltip.unbind();
tooltip = null;
});
Can some one explain me what went wrong? Why im getting this exception and how I can prevent it?

Related

Vuetify Data-Table Header array not accepting empty child associations

I have a data-table using Vuetify that passes a localAuthority prop from a rails backend. It all works really well until I pass an empty child association (nested attribute). In this case 'county':
<script>
import axios from "axios";
export default {
name: 'LocalAuthorityIndex',
props: {
localAuthorities: {type: Array, default: () => []},
counties: {type: Array, default: () => []},
localAuthorityTypes: {type: Array, default: () => []}
},
data() {
return{
search: '',
dialog: false,
testmh: 'hello',
dialogDelete: false,
headers: [
{ text: 'Name', align: 'start', value: 'name' },
{ text: 'ONS Code', value: 'ons_code' },
{ text: 'ID', value: 'id' },
{ text: 'Population', value: 'population' },
{ text: 'county', value: 'county.name' },
{ text: 'Website', value: 'website' },
{ text: 'Actions', value: 'actions', sortable: false },
],
So in the example above it works as long as all records have a county association (belongs_to). However, if one record does not have a 'county' associated with it then I get the following error:
[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'name')"
I have tried lots of things like adding in a conditional statement like below:
{ text: 'county', value: ('county.name' ? 'county.name' : nil )},
But nothing seems to work.
According to your <v-data-table> code at Codepen, I see that you are overriding default table item slots with your own.
Your error are from this part of code:
...
<template #item.county.name="{ item }">
<a :href="'/counties/' + item.county_id">
{{ item.county.name }}
</a>
</template>
...
Take a look at first string. #item.county.name is a short form of v-slot:item.county.name and comes from one of your strings in headers array:
...
{ text: 'county', value: 'county.name' },
So there's no error, this part are correctly parsed by vuetify library even when your item will not contain any county.
The error is in 3rd string of the above code. You are trying to print name of county without checking its existence. That's why you are getting ...Cannot read properties of undefined... error.
I guess you may fix your issue this way:
<template #item.county.name="{ item }">
<a :href="'/counties/' + item.county_id">
{{ item.county ? item.county.name : 'No name' }}
</a>
</template>
Of course, if you need to hide your link to counties in this case, you may also add v-if (or v-show) into a tag.
I also created a small Codepen with some static data. Take a look into item.name.text slot in this playground, maybe it will help you to understand similar object associations.

Vue Testing - '... .push is not a function'

Im trying to test a method of a component that adds a new entry to an already existing object.
addTag: function () {
this.value[this.field.key].push(this.tag)
this.tag = ''
}
I am just trying to call that method inside my test via
wrapper.setProps({
field: {
key: 'tag'
},
value: {
tag: {}
}
})
...
wrapper.vm.addTag()
but it throws and error
TypeError: this.value[this.field.key].push is not a function
Ive set all needed data and props beforehand (field.key and tag), so that's not the problem. running other methods works completly fine, push seems to be the problem
This is because this.value['tag'] is an object, not an array, so there is no push method.
Defining it as an array instead would change that:
wrapper.setProps({
field: {
key: 'tag'
},
value: {
tag: []
}
})

Pass data between prompts

Can i pass data between two prompts in yeoman?
Eg i've got two prompts like
{
type: 'input',
name: 'Name',
message: 'Name?'
},{
type: 'input',
name: 'package',
message: 'Package?',
default: 'org.my.app.'+<prompt.name>
}
I want to show name property as default value for package? One way i can think of is:
Show a template in default (like in example)
Change the value later when creating the final template for user.
Another way that i tried is using when
{
type: 'input',
name: 'Name',
message: 'Name?'
},{
when: (response) => {
this.testValue = response.Name
return true
},
type: 'input',
name: 'package',
message: 'Package?',
default: 'org.my.app.'+this.testValue
}
but it gives undefined even though inside the function value has been stored for in this.testValue
Is there any better way?
i finally found the answer. The way to achieve it is using two prompt variables and running the second one after first's promise returns
const prompt1 = [{
type: 'input',
name: 'Name',
message: 'Name?'
}];
return this.prompt(prompt1).then(props => {
const prompt2 = [{
type: 'input',
name: 'package',
message: 'Package?',
default: 'org.my.app.'+props.name
}];
return this.prompt(prompt2).then(props => {
//code goes here
});
});

Javascript reset object inside array

I have the below JS code in my Ember app that gets called;
myPanels.accordionPanels = [];
myPanels.accordionPanels.push({
panel: {
name: "my-grid",
type: 'comp',
props: [{
key: 'elementId',
value: "myCustomId"
}]
}
});
So as you can see, I start by setting myPanels.accordionPanels = [] every time and then push the object.
However, I got the following error
Assertion Failed: Attempted to register a view with an id already in
use: myCustomId
So I am assuming that the object inside is not getting reset & it is able to find the earlier created "myCustomId".
Am I resetting the array (or rather the object inside it) correctly ?
Since I am able to push values using:
accordionPanels = [];
accordionPanels.push({
panel: {
name: "my-grid",
type: 'comp',
props: [{
key: 'elementId',
value: "myCustomId"
}]
}
});
make sure myPanels.accordionPanels doesn't have any prototype associated with it.
Try to inspect its value as:
myPanels.accordionPanels = [];
console.log(myPanels.accordionPanels); // see if it has values.
You can delete value using :
delete myPanels.accordionPanels PROTOTYPE

Uncaught TypeError: 'optionValues' must be of type {Array.<Array>|Array.<{name: string, values: Array.<Array>}>}

I am trying to integrate select2 in backgrid.js. Backgridjs has extension support for select2 and the code for that is
{
name: "gender",
cell: Backgrid.SelectCell.extend({
optionValues: [["Male", "m"], ["Female", "f"]]
}),
label: "Gender (SelectCell)"
}
so based on this i tried something like the below since i have to load values to select2 box from the server
var FetchSecurities = Backbone.Model.extend({
url : Hexgen.getContextPath("/referencedata/securities")
});
var fetchSecurities = new FetchSecurities();
{
name: "security",
label: "Security",
cell: Backgrid.Extension.Select2Cell.extend({
optionValues: fetchSecurities.fetch({
success : function() {
for(var objectPlace in fetchSecurities.attributes) {
[[fetchSecurities.attributes[objectPlace].security],[fetchSecurities.attributes[objectPlace].security]];
}
}
}),
})
}
but i get this exception, I am sure i make mistake when constructing the value for the select2 box but don't know how to fix it, Please help me to get it done.
Uncaught TypeError: 'optionValues' must be of type {Array.<Array>|Array.<{name: string, values: Array.<Array>}>}

Categories