Conditional V-HTML rendering - javascript

Just wondering if there is something I'm missing here:
<span v-html="(shouldParseHTMLBool ? HTMLContent : '')">
{{ contentWithoutParsedHTML }}
</span>
doens't appear to work.
I would like to have this span interpreting HTML only if shouldParseHTMLBool is set to true.
Is it something possible, or should I use a v-if? In this trivial example it's not a big deal, but with my components I'll have to duplicate ~30 lines for each condition.

It's better to make if condition away from template as much as possible.
You should create a computed object instead.
[template]
<span v-html="computedContent"></span>
[script]
...
computed: {
computedContent: function () {
return this.shouldParseHTMLBool ? this.HTMLContent : ''
}
},
...

The v-html directive replaces the innerHTML of the element. In your case, the {{ contentWithoutParsedHTML }} will be replaced with the value of (shouldParseHTMLBool ? HTMLContent : '')
You can do something like
<template>
<span v-html="conditionalParse"></span>
</template>
<script>
methods: {
conditionalParse: function () {
return this.shouldParseHTMLBool ? this.HTMLContent : ''
}
</script>

try this
<span v-if="shouldParseHTMLBool" v-html="HTMLContentForIfCondition" >All</span>
<span v-else v-html="HTMLContentForElseCondition" ></span>
You can use two spans, One for v-if is true and other for v-else

Related

Why constructor not change server status and background color in Angular?

I have a little problem with my constructor. Imo I don't have any mistakes, so it should work fine, but something not works.
I have 2 Angular files - server.component.html and server.component.ts
server.component.html
<p [ngStyle]="{backgroundColor: getColor()}">{{ 'Server' }} with ID {{ serverId }} is {{ getServerStatus() }}</p>
server.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-server',
templateUrl: './server.component.html'
})
export class ServerComponent {
serverId: number = 10;
serverStatus: string = 'offline';
conctructor() {
this.serverStatus = Math.random() > 0.5 ? 'online' : 'offline';
}
getServerStatus() {
return this.serverStatus;
}
getColor() {
return this.serverStatus === 'online' ? 'green' : 'red';
}
}
So constructor should change my status and color. They don't do it, I have only red because I have only offline status. What's going on? I do the course, and I have the same code what my mentor.
enter image description here
css property is background-color not backgroundColor. Also, you missed single quotes(') around the background-color text in HTML. Update your html to this:
<p [ngStyle]="{'background-color': getColor()}">Server with ID {{ serverId }} is {{ getServerStatus() }}</p>
Use a function on template could give you performace issue so I suggest to change it by template variables.
<p [ngStyle]="{'background-color': serverStatus === 'online' ? 'green' : 'red' }">{{ 'Server' }} with ID {{ serverId }}
is {{ serverStatus }}</p>
And remove getServerStatus() and getColor() functions
There is nothing wrong here. It may cause of misspell your constructor name constructor instead of conctructor, Because of this Angular consider your method conctructor as method not a class lifecycle.
Please refresh this page based on value it change the color:
Reference: https://stackblitz.com/edit/angular-dga6ds?file=src%2Fapp%2Fapp.component.ts

Conditionally render a badge for active/inactive User

I am trying to render conditionally a badge, based on the logged condition of a user. If the props coming from the server is true, then the badge is green, else grey.
I have tried various solutions, from basic if/else in the JSX, to classNames but the badge isn't being render.
My Code:
{user.loggedIn ? (
<div
className={classNames('badge badge-pill', {
'badge-success': user.loggedIn,
'badge-danger': !user.loggedIn
})}
/>
I don't see anything wrong with the code. I mean the item should have rendered, with multiple solutions. Any ideas, what I am doing wrong.
<span
className={
user.loggedIn ? 'badge badge-pill badge-success' : 'badge badge-pill badge-muted'
}
/>
I have tried this as well.
I can see the element in the React-Dev-Tools, being render correctly, witht the right prop, but I cannot see it render in the screen.
Your contents will only get rendered if user is loggedIn. Also the div tag must be closed inside the condition { isLoggedIn }
you should try something like this:
{user.loggedIn ? (
<div className={'badge badge-pill badge-success'}>ENTER YOUR CONTENT HERE</div>) : (
<div className={'badge badge-pill badge-danger'}>ENTER YOUR CONTENT HERE</div>
)}
but since the div is self-closing and has no contents, it doesn't display it, so add some content too
The badge for logged out user will never be displayed as you put a rendering condition around all the div with user.loggedInd ? (yourComponent...)
If user.loggedIn is boolean, then you can just write
<div
className={
classNames('badge badge-pill', {
'badge-success': user.loggedIn,
'badge-danger': user.loggedIn
})
}
/>
I think it's better to avoid conditional in jsx directly. You can do something like this:
let attachClass = ['badge', 'badge-pill']
if(user.loggedIn){
attachClass = [...attachClass, 'badge-success'].join(' ');
}else{
attachClass = [...attachClass, 'badge-danger'].join(' ');
}
Than you can just return one div with className attach class:
<div className={attachClass}></div>
The issue look into the user.loggedIn is not defined or return false
const loggedIn = true;
<span className={loggedIn ? 'badge-success' : 'badge-muted'}>
Css Change </span>
Codepen

Angular translate filter in ternary operator

I'm trying to translate my project into another language. I used angular translate library and provided an external JSON file with the translations. It looks like this:
{
"hello_world": "Hola Mundo"
}
When I'm using it with simple hardcoded strings it works just fine and I get my correct translations:
<p>{{ "hello_world" | translate }}</p>
But how to deal with the ternary operator in code like this?
<button> {{ conditionValue ? 'Show' : 'Hide' }} </button>
How to change those 'Show' and 'Hide' values into a translation filter with Angular Translate? I tried different ways but I got an invalid syntax errors.
Thanks!
I think if you wrap the ternary operator into (), it will work.
<button> {{ ( conditionValue ? 'Show' : 'Hide' ) | translate }} </button>
you may try for this:
here i make username online and offline when you choose soanish, the user online status will change into spnish based on ternary condition.
https://plnkr.co/edit/o16dpI?p=preview
[https://plnkr.co/edit/o16dpI?p=preview][1]
{{ ( userName ? 'Show' : 'Hide' ) | translate }}
I've just come up with the solution!
For ternary operators we have to use 'translate' directive instead of filter. And it works just fine:
{
"show_value": "Show",
"hide_value": "Hide",
}
<button translate> {{ conditionValue ? "show_value" : "hide_value" }} </button>
If exist prefix
{{ ('massmedias.' + (ctrl.actionType === 'add' ? 'add' : 'rename')) | translate }}
Here is your language JSON file
"CONFIGURATION": {
"NEW_TEMPLATE": "New Template",
"EDIT_TEMPLATE": "Edit Template"
}
CASE-I (With HTML tag)
<button> {{ ( variable === '5' ? 'CONFIGURATION.NEW_TEMPLATE' : 'CONFIGURATION.EDIT_TEMPLATE' ) | translate }} </button>
CASE-II (With some third party attribute)
<p-dialog header="{{(variable === '5' ? 'CONFIGURATION.NEW_TEMPLATE' : 'CONFIGURATION.EDIT_TEMPLATE') | translate}}">

Setting initial value for computed property with vuejs

I'm trying out vuejs by following along with the laracasts series of webcasts on this. In https://laracasts.com/series/learning-vue-step-by-step/episodes/6, Jeffery Way has put the code in the http://jsfiddle.net/d4f27e5p/ .
The initial setting is shown in the screenshot, before any plan is selected. I would like to set a default value in the button of "please select " (instead of "Downgrade") The button code is:
<span v-else>
<button #click="setActivePlan">
{{ isUpgrade ? 'Upgrade' : 'Downgrade' }}
</button>
How can I do this?
How about adding a computed property for the button text that includes the additional logic? Something like this:
buttonText: function() {
if(!this.active.name)
return "Please Select";
return this.isUpgrade ? 'Upgrade' : 'Downgrade';
}
Then the button would use this:
<span v-else>
<button #click="setActivePlan">
{{ buttonText }}
</button>
</span>
Here's an updated jsfiddle.

Is there a way to pass a variable with curly brace template tags through a method?

I have an ng-repeat where I run an ng-if with a method that checks to see if certain parameters match between two sets of data. If there's a match, it updates $scope with the current match, which I can use to output my template:
<div ng-repeat="repeatedItem in repeatedItems">
<a href="" ng-if="!matchData(repeatedItem.item1, repeatedItem.item2)">
<img ng-src="{{ matchedItem.falseImageUrl }}" />
</a>
<a href="" ng-if="matchData(repeatedItem.item1, repeatedItem.item2)" ng-click="open(matchedItem.id)">
<img ng-src="{{ matchedItem.imageUrl }}" />
<time>{{ matchedItem.date }}</time>
<div class="button-wrapper">
<button class="btn">{{ matchedItem.text }}</button>
</div>
</a>
</div>
The thinking is that everything out of repeatedItems needed to show, unless an item in repeatedItem matched another data set, in which case you'd show the matchedItem instead.
Everything works fine, except for the ng-click="open(matchedItem.id) bit. Because matchedItem.id isn't wrapped in template tags, ng-click is always calling the latest iteration of matchedItem, so for all but the last repeated element, it's opening the wrong link.
The most obvious solution in my Angular-inexperienced mind would have been to do something like ng-click="open( {{ matchedItem.id }} ), but that throws an error. My next idea was something like ng-click="open( {0} ):{{ matchedItem.id }} - a printf-type of solution, but I haven't found any built-in Angular solution for that. I also thought about stashing {{ matchedItem.id }} in an attribute somewhere (data-id="{{ matchedItem.id }}"?), but I'm not sure how to call that attribute in the method.
It's possible (probable?) that I'm just not "thinking in Angular" yet, and I'm going about this the wrong way entirely. Or perhaps there's a directive that I'm just not aware of?
Here's the method:
$scope.matchData = function(item1, item2) {
var isItAMatch = false;
for (i=0; i<$scope.repeatedItems.length; i++) {
itemAToMatch = $scope.repeatedItems[i].itemA;
itemBToMatch = $scope.repeatedItems[i].itemB;
if (itemAToMatch == item1 && itemBToMatch == item2) {
isItAMatch = true;
$scope.matchedItem = $scope.repeatedItems[i];
break;
}
}
return isItAMatch;
}

Categories

Resources