*ngIf window.location.href.indexOf is not working - javascript

I need to show one element only if location is right, if not, it shoudn't be shown.
This is not working:
<div *ngIf="!accessTrue() && window.location.href.indexOf('something')" > -1)>
CODE
</div>

you cannot access the window object inside the template.
But you can define a getter in your component :
get hasSomething(){
return window.location.href.indexOf('something') > -1
}
then :
<div *ngIf="!accessTrue() && hasSomething">
CODE
</div>
Note that it might be cleaner to use an ActivatedRoute if your parameter is accessible through it.

In HTML :
<div *ngIf="hasAccess"> CODE </div>
In angular Component :
constructor(){
this.hasAccess = window.location.href.indexOf('something') > -1 && !this.accessTrue();
}

Related

How to access object property in angular using string interpolation?

I have this object in my component ts file that looks like this:
someData = {
someValue: null,
unit: "centimeters"
},
In my template (html file) I have to verify the value of "someValue" property. If its value is null then display the unit, else display the value of someValue and unit together. I have the below code but it doesn't seem to work. Can anyone point me in the right direction? Thanks in advance!
<div>{{ someData?.someValue === null ? someData?.someValue.unit : someData?.someValue someData?.unit }}</div >
You can use ngif to check the condition and show the data:
<div *ngIf="someData?.someValue === null">{{someData.unit}}</div>
<div *ngIf="someData?.someValue!= null">{{someData.someValue}} {{someData.unit}}</div>
Your two values at the end aren't going to render right, because it's executable javascript, not HTML when inside the double brackets.
I would suggest splitting this into two lines of HTML.
<div *ngIf="someData?.someValue; else unit_only">{{someData.someValue}} {{someData.unit}}</div>
<ng-template #unit_only>{{someData?.unit}}</ng-template>
Or you could try sticking with your original approach...
<div>{{ someData?.someValue === null ? someData?.unit : someData?.someValue + ' ' + someData?.unit }}</div>

Is it possible to align a div based on a condition?

I have a div which I have set to align="right". I have created a local variable called userId and assigned 1 to it and I am wondering if is possible to somehow set the div to left align if userId === 1, which will be the case. I've tried reading the react docs on conditional rendering but I don' believe that is what I'm looking for as they all deal with rendering whereas the div that I want to align is being returned by an export function so the render function isn't used.
export function MessageRow({ message, fetch }) {
return (
<div>
<br />
<div align="right" className="Message-Body">
<div className="Message-row-header">{message.user}</div>
<div>{message.content}</div>
<div className="muted-text">
(Sent: {new Date(message.timestamp).toUTCString()})
</div>
<div>
<button
className="block"
onClick={() => messageService.delete(message.id).then(fetch)}
>
Delete
</button>
<button className="block">Edit</button>
</div>
</div>
</div>
);
}
This is what I currently have and was thinking of trying a function like below but I am unsure how I would then get it to apply to the div.
function checkMessageUserID(userId) {
if (userId === 1) {
}
}
It is still being used from a render() point of view though, no?
So you could still do what you want:
return (
<div><br />
{userId !== 1 ?
<div align="right" className="Message-Body">
:
<div align="left" className="Message-Body">
}
...
1) You can return JSX from the function and call the function inside return.
function checkMessageUserID(userId) {
if (userId === 1) {
<div align="right" className="Message-Body">
}
else{
<div align="left" className="Message-Body">
}
}
Then inside return call {checkMessageUserID()}
2) You can also use ternary operator inside your render.
<div align = {userID == 1 ? "right" : "left"} className="Message-Body">
Conditional rendering works the same for functional as well as stateful components.
Working code snippet below.
<div align={userId === 1 ? 'left' : 'right' } className="Message-Body">
You could do any of the above, or what I would recommend is, you create two styling classnames, you can call them 'left/right-message' or 'mine/otherPerson-message' and you can assign align: 'left/right' to each, you can even assign different colors for that chat feel, you'd achieve this simply by doing:
<div className={userId === 1 ? "left-message" : "right-message" >
...
</div>

React conditional classnames using template strings and && operator

There have been many questions on StackOverflow relating to applying conditional classnames to React components; however, I have not seen a good answer for this particular situation:
I have a basic div that I want to conditionally apply the "is-required" class. Here is my approach:
<div className={`some-class ${isRequired && 'is-required'}`}>
The main issue here is that when isRequired is false, then my compiled HTML code ends up looking like this:
<div class='some-class false'>
Obviously, I could use a ternary operator like this so I can return an empty string instead:
<div className={`some-class ${isRequired ? 'is-required' : ''}`}>
But then in the compiled HTML code there is this extra random space included in the class, which won't cause any rendering issues, but I still don't like it:
<div class='some-class '>
Even still, I could remove the space after "someClass" and include it before "isRequired", but now it's harder to read and feels kind of clunky:
<div className={`some-class${isRequired ? ' is-required' : ''}`}>
I have heard of utilities such as classnames, but I am looking for a simple solution where I don't need any additional packages.
What is the recommended approach here?
Actually, there are many ways to do that, here's one of them.
<div className={isRequired ? 'some-class is-required': 'some-class'}>
or you can return null
<div className={isRequired ? 'is-required' : null}>
In order, if you have several classes.
<div className={isRequired ? 'some-class is-required': isDisabled ? 'some-disabled-class' : 'some-class'}>
https://reactjs.org/docs/conditional-rendering.html
class App extends React.Component {
constructor() {
super();
this.state = {
isRequired: false
};
}
render() {
return (
<div className="App">
<div className={this.state.isRequired ? 'is-required' : null}>Null</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'></div>
Maybe you'll find this utility function helpful (it will be used as a tagged template):
const c = (strings = [], ...classes) => {
let myClass = '';
strings.forEach((s, i) => {
myClass += s + (classes[i] || '');
});
return myClass.trim().replace(' ', ' ');
}
Now you can use it like this :
className={c`my-class ${this.props.done && 'done'} selected`}
or
className={c`some-class ${isRequired && 'is-required'} ${isDisabled && 'some-disabled-class'}`}
You can use it if you don't want false value.
<div className={`some-class${isRequired && ' is-required' || ''}`}>
<div className={isRequired && 'is-required'}>Required</div>
Using evaluation short circuiting (https://en.wikipedia.org/wiki/Short-circuit_evaluation)
I highly recommend using this package for joining class names if you are using an import/export system.
https://www.npmjs.com/package/classnames

Dynamic classes using ng-repeat in AngularJS

This is not a duplicate.
In the other post, they are just doing a ternary operation. I wanna changes classes within ng-repeat.
I have this piece of code with little bugs.
HTML:
<div id="server-id-list-container" class="panel-body col-md-12 scrollbar">
<div class="server-id-list-element" ng-class="serverIdLength > 12 ? 'col-md-3' : 'col-md-2'" ng-repeat="server in selection.serverIds">
<p class="alert alert-info">{{server.serverId}}<span ng-click="removeServerId($index)" class="glyphicon glyphicon-remove"></span></p>
</div>
</div>
Controller:
_.forEach($scope.selection.serverIds, function(a) {
$scope.serverIdLength = a.serverId.length;
});
Scope Object:
[
{
"serverId": "loma1pwipdb2002",
"serverName": "",
},
{
"serverId": "shdmqprtp1",
"serverName": "",
}
]
When I enter "loma1pwipdb2002", the class becomes col-md-3 and since I am using ng-repeat applies for all elements. I want the class to be applied only to serverIdLength > 12 and if its lesser than 12, col-md-2 should get applied.
Please advice.
Is it correct that you want to switch your class for each element of selection.serverIds list separately based on serverId string length? Need to know your selection.serverIds, is it your "Scope Object"? If yes, then I would do just
<div
class="server-id-list-element"
ng-repeat="server in selection.serverIds"
ng-class="server.serverId.length > 12 ? 'col-md-3' : 'col-md-2'"> ... </div>
The problem is that your $scope.serverIdLength is being calculated once for all the list. While you want to have a dynamic class based on each item specific property.
Let's continue discussion if I didn't understand the issue and the entry conditions.
the issue seems to lie here:
_.forEach($scope.selection.serverIds, function(a) {
$scope.serverIdLength = a.serverId.length;
});
No matter what $scope.serverIdLength will always be set to the length of the last serverId. That because it's a global variable and there is only one instance of it. This is why all your classes match. They all reference the same variable.
Instead like #dhilt suggested ditch the controller code and acccess the length in the dom:
ng-class="server.serverId.length > 12 ? 'col-md-3' : 'col-md-2'"
Try that:
ng-class="{'col-md-3':server.serverId.length > 12, 'col-md-2':server.serverId.length <= 12}"

Angularjs if-then-else construction in expression

Can I somehow use if-then-else construction (ternary-operator) in angularjs expression, for example I have function $scope.isExists(item) that has to return bool value.
I want something like this,
<div ng-repeater="item in items">
<div>{{item.description}}</div>
<div>{{isExists(item) ? 'available' : 'oh no, you don't have it'}}</div>
</div>
I know that I can use function that returns string, I'm interesting in possibility of using if-then-else construction into expression.
Thanks.
Angular expressions do not support the ternary operator before 1.1.5, but it can be emulated like this:
condition && (answer if true) || (answer if false)
So in example, something like this would work:
<div ng-repeater="item in items">
<div>{{item.description}}</div>
<div>{{isExists(item) && 'available' || 'oh no, you don't have it'}}</div>
</div>
UPDATE: Angular 1.1.5 added support for ternary operators:
{{myVar === "two" ? "it's true" : "it's false"}}
You can use ternary operator since version 1.1.5 and above like demonstrated in this little plunker (example in 1.1.5):
For history reasons (maybe plnkr.co get down for some reason in the future) here is the main code of my example:
{{true?true:false}}
You can easily use ng-show such as :
<div ng-repeater="item in items">
<div>{{item.description}}</div>
<div ng-show="isExists(item)">available</div>
<div ng-show="!isExists(item)">oh no, you don't have it</div>
</div>
For more complex tests, you can use ng-switch statements :
<div ng-repeater="item in items">
<div>{{item.description}}</div>
<div ng-switch on="isExists(item)">
<span ng-switch-when="true">Available</span>
<span ng-switch-default>oh no, you don't have it</span>
</div>
</div>
This can be done in one line.
{{corretor.isAdministrador && 'YES' || 'NÂO'}}
Usage in a td tag:
<td class="text-center">{{corretor.isAdministrador && 'Sim' || 'Não'}}</td>
I am trying to check if a key exist in an array in angular way and landed here on this question. In my Angularjs 1.4 ternary operator worked like below
{{ CONDITION ? TRUE : FALSE }}
hence for the array key exist i did a simple JS check
Solution 1 : {{ array['key'] !== undefined ? array['key'] : 'n/a' }}
Solution 2 : {{ "key" in array ? array['key'] : 'n/a' }}

Categories