I'm trying to do the following in my Vue application:
<template v-slot:cell(selected)="{ item }" >
<b-checkbox
v-model="item.selected != undefined ? item.selected : defaultCheckbox"
></b-checkbox>
</template>
I have to make sure item.selected is not undefined or else I get an error Cannot read properties of undefined (selected). When I use the conditional ternary operator in my v-model, I get a Syntax Error: Unexpected token. Why is that? How do I fix this so that I can still use item.selected even if it's not defined?
You can use v-if/else directives to define checkboxes for both cases:
<b-checkbox v-if="item.selected"
v-model="item.selected"
></b-checkbox>
<b-checkbox v-else
v-model="defaultCheckbox"
></b-checkbox>
Related
Let's say I have an array of objects:
public arr: {val: string}[] = [];
Now I want to access the first object, but the array can be empty also.
The compiler guesses that this is OK, but it will fail during runtime - obviously:
<app-comp [value]="arr[0].val"></app-comp>
<div>{{ arr[0}.val }}</div>
Using the ?. operator works, but it will throw a warning:
<app-comp [value]="arr[0]?.val"></app-comp>
<div>{{ arr[0}?.val }}</div>
Warning NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator
Now the solution that works for me is this:
<app-comp [value]="arr[0] && arr[0].val"></app-comp>
<div>{{ arr[0] && arr[0].val }}</div>
But it bloats the template. Is there a more elegant solution to this problem?
Using *ngIf will only work sometimes, when <app-comp> or the <div> parent can be omitted. Which will not always be the case.
You can use ng-container tag. This tag does not add any element and any parent elements will not be removed.
<ng-container *ngIf="arr[0]; let obj">
<app-comp [value]="obj.val"></app-comp>
<div>{{ obj.val }}</div>
</ng-container>
A few days, i try to trim the response value in a vue condition.
I need this, when the value is null or empty apply the condition.
<li v-if="item[0].otrodl4.trim() == ''" class="progress-step">
But I got the error
vue.js:597 [Vue warn]: Error in render: "TypeError: Cannot read property 'trim' of null"
The problem is that some values bring only whitespace and no more, that should be considered null or empty.
E.G.
I tried it with filters but I get the same error.
Thanks for read.
Greetings.
Try this:
!item || !item[0] || !item[0].otrodl4 || item[0].otrodl4.trim() == ''
Basically, you have to check that item is defined and not null. And that the first element of that array exists AND that this element has otrodl4 property.
Try this:
item[0] && item[0].otrodl4.trim() == ''
So, the only time it checks if item[0].otrodl4.trim() == '' is if there's a value in the 0 index position of the item array.
It's known as a short-circuit conditional and you can read all about it here.
I have tried with trim() and it is working fine. please try if this can be help to you.
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.js"></script>
</head>
<body>
<div id="app">
<!--if only space in text it will display "hello space" else no dsplay. -->
<p v-if="text.trim()==''">hello whitespace {{ text | trim }}</p>
</div>
<script>
new Vue({
el: '#app',
data: function() {
return {
text: ' ' // added only a space
}
}
});
</script>
</body>
</html>
This is a TypeError where the variable you are trying to manipulate is not what it is thought to be by the developer.
Always happen to a language without proper typing.
Therefore, you can do an optional chaining and check the variable is what it is supposed to be first.
ES2020 has allowed us to use optional chaining to type check.
For example,
v-if="!!item?.[0]?.otrodl4?.trim && item?.[0]?.otrodl4?.trim() == ''"
!! is a type conversion to falsy values like null or undefined or empty string to become false.
It makes sure that otrodl4 has a property method trim before calling the method and therefore won't cause TypeError anymore.
I would lik to you use the following Ternary operator within React JSX:
<Table.Cell>{`${user.company !== null ? <Link to={`/companies/${user.company._id}`}>`${user.company.name}`</Link> : '' }`}</Table.Cell>
I get however the following value displayed: [object Object]
When I use this Ternary operator, the value is displayed right:
<Table.Cell>{`${user.company !== null ? `${user.company.name}` : '' }`}</Table.Cell>
And when I use this JSX code without the Ternary operator, the value is also right:
<Table.Cell><Link to={`/companies/${ user.company._id}`}>{user.company.name_company}</Link></Table.Cell>
However, I would like to use a conditional React Router Link tag to create an hyperlink. I have the same problem with usage of other HTML tags within the Ternary operator.
What am I am doing wrong?
Your syntax is not right. You should rewrite your ternary check in JSX like this:
<Table.Cell>{ user.company !== null ? <Link to={`/companies/${user.company._id}`}>{user.company.name}</Link> : null }</Table.Cell>
Or you can check it this way:
<Table.Cell>{ user.company !== null && <Link to={`/companies/${user.company._id}`}>{user.company.name}</Link> || null }</Table.Cell>
Hope this helps.
I have a problem setting ng-checked to true for checkboxes based on whether a value is undefined or not. For example in the following code..
<input class="custom-checkbox form-control" id="{{ point.pointId }}-{{ value }}"
type="checkbox"
ng-true-value="'{{ value }}'"
ng-model="item.sections[inspectionSection.sectionShortName[point.pointId].value">
I am trying to set ng-checked by checking if value, which can be set to one of several values, is defined.
For example something like:
ng-checked={{ if(value !== undefined) }}
I can't seem to get it working. Anything I try in ng-checked either checks all the checkboxes or none. Any help much appreciated!
I would recommend using a function in this case.
ng-checked="isNotUndefined(value)"
// in the controller
isUndefined (value) {
return value !== undefined
}
You can accomplish this by using the ternary operator:
ng-checked="value !== undefined ? true : false"
I have a projects object like so
projects: {
projectType: {id: 1, title:'something'},
budgetType: {id: 1, title:'something'},
projectStatus: {id: 1, title: 'something'}
}
and im rendering this in the render method.
<td>{this.props.projects.projectType.title}</td>
<td>{this.props.projects.budgetType.title}</td>
<td>{this.props.projects.projectStatus.title}</td>
This works fine, but sometimes the server sends in null when that object is not present as it is not a required field to be entered. So, this throws a "cannot read property of null error". I was using a ternary operator in each case to solve this error which doesnt look really nice. Is there any better way to solve this?
<td>{(this.props.projects.projectType.title)?this.props.projects.projectType.title: ''}</td>
EDIT:
I have a "ProjectList" component which lists all the project rows like so
//in render
<tbody>
{Object.keys(this.props.projects).map(this.renderProject)}
</tbody>
//renderProject Function
<Project key={key} project={this.props.projects[key]}/>
When accessing properties of null Javascript will throw this error. One usual pattern we use is like:
this.props.projects.projectType && this.props.projects.projectType.title
Here the second expression is evaluated only if first one is true. null and undefined are false so the second one won't be evaluated, an no error thrown.
This is because false && <whatever> === false
If projectType is not null, the value of the expression will be equal to the last item in the chain.
This can be chained in fancy ways like:
this && this.props && this.props.projects && this.props.project.projectType;
But it is always recommended to keep these checks inside the javascript file and use some derived attribute for the view.
I don't know if ampersand is a valid token in react expressions. Please refer to other answers on how such cases are handled in React way.
Why not create a simple helper method which accepts the property and returns either the value or an empty string if its null? You would still do the ternary operator but only in one place