How to check if element exists in an Object? - html

How to use *ngIf to check if an element exists in an Object?
.ts file
this.data = ["cat", "dog"];
I want to check, in my html file, if cat exists in the object this.data or not. Can I do that with an *ngIf ?

you can create a function in your ts file to check if the wanted string exists in the array or not like this :
doesExist(animal: string): boolean {
return this.data.includes(animal);
}
and then call it in your html file :
<div *ngIf="doesExist('cat')"> [...] </div>

<div *ngIf="data.includes('cat')">hello world</div>
I hope this will help.

You can use ngFor first to iterate every element in a loop and then use ngIf to check if value exist or not.
for example:
<div *ngFor="let element of data">
<div *ngIf="element.cat">
</div>
</div>
Another method is make seperate function for this but I think this is easy way to do.I hope it will help you.:)

Related

How to Iterate JSON properties in TypeScript

My question is very simple, I have a following JSON Typescript Object and I like to Iterate trought the JSON properties
{"work_type":"Fabricación","work_type_resp":"Mesa","looking_for":"Relación Calidad/Precio","image":"https://s3-sa-east-1.amazonaws.com/online-quotation-images/153366018967.png","width":"22","high":"34","depth":"","modifications":"mod"}
The code used is the following angular TypeScript component:
export class DetailsOnlineQuoteModalComponent implements OnInit {
#Input() title;
#Input() values:string;
properties:JSON;
constructor(public activeModal: NgbActiveModal) { }
ngOnInit() {
this.properties=JSON.parse(this.values);
console.log(this.properties);
}
}
What I really need is to go through the key-value attributes of the JSON and show them in my HTML.
Many Thanks!
If you are using angular 6.1 use keyvalue pipe
<div *ngFor="let title of data | keyvalue">
{{title.key}}
</div>
For Angular 5
<div *ngFor="let key of dataKeys">
{{key}} ------------- {{data[key]}}
</div>
get dataKeys() { return Object.keys(this.data); }
Example:https://stackblitz.com/edit/keyvalue-pipe-qtaqnm
As per your comment, I'm assuming you want to do an ngFor on the HTML to display each one of the key-value pairs
<div *ngFor="let key of Object.keys(properties)">
{{properties[key]}} --> this is the value
</div>
You can get all the keys using Object.Keys and assign to a variable as follows,
this.properties=JSON.parse(this.values);
let response = Object.keys(this.propertie);
now you can use ngFor over it,
<div *ngFor="let key of response ">
{{properties[key]}}
</div>
component.ts
let obj = {"work_type":"Fabricación","work_type_resp":"Mesa","looking_for":"Relación Calidad/Precio","image":"https://s3-sa-east-1.amazonaws.com/online-quotation-images/153366018967.png","width":"22","high":"34","depth":"","modifications":"mod"}
this.keyOfObj = Object.keys(obj);
html
<div *ngFor="let key of keyOfObj ">
{{obj[key]}}
</div>
unfortunately seems to be NOT working (with keyvalue) with ANGULAR_9
see here for a comparison of full different way of doing: https://stackblitz.com/edit/angular9-iterate-on-object-attribute
otherwise the answer by defining a method to do the job is still working.

Angular: Send element from HTML

Is there a way to send through HTML the element as an attribute? For example:
In HTML:
<ul>
<li *ngFor="let item of items">
<my-component [ngClass]="{'whatever': checkElement(my-component)}">
</li>
</ul>
In ts file:
checkElement(el): boolean {
// dummy code
const size = el.getBoundingClientRect();
return size.bottom > 100;
}
I know there are several ways to get that element, but this will be used in a huge loop and I would like to prevent searching the element in the DOM (if possible).
Thanks!
You can you a template reference variable to refer to my-component like so:
<my-component [ngClass]="{'whatever': checkElement(myComponentVariableName)}" #myComponentVariableName>
and pass that as an argument to the method checkElement(). Note that here the type of myComponentVariableName will be HTMLInputElement.
Another way to access that from the .ts file would be to use #ViewChild() like so:
#ViewChild('myComponentVariableName') myComponentVariable: ElementRef;`.
Then you can use this.myComponentVariable anywhere inside the component.
If you are worried about having multiple my-components as it is inside an *ngFor, you can convert the #ViewChild statement to make it a list like so:
#ViewChildren(my-component) myComponentList: QueryList<my-component>;
Also, track the *ngFor by index, and send the index along with the template reference variable like so:
<li *ngFor="let item of items; let i=index;">
<my-component [ngClass]="{'whatever': checkElement(myComponentVariableName, i)}" #myComponentVariableName>
</li>
Inside the checkElement() method, access the particular my-component like myComponentList[i].
Sure, very easy :
export class ParentComponent {
this = this;
}
<my-element [parentElement]="this">
now in your second component
#Input('parentElement') parentElement: ParentComponent;

ng-bind-html not working with my $scope.variable

I am trying to add something like dynamic HTML using ng-bind-html but its not working with $scope variable
Here is my Angular code
1)My controller
$scope.name = "Parshuram"
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Also that my string is dynamic
"<div><table class=" + "\"table table - bordered table - responsive table - hover add - lineheight table_scroll\"" + "><thead><tr><td>Name</td><td>Age</td></tr></thead><tbody><tr ng-repeat=" + "\"tr in dyna\"" + "><td>{{tr.name}}</td><td>{{tr.age}}</td></tr></tbody></table></div>"
So i cant replace every variable with $scope
2)- My HTML
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml"></div>
</div>
I got this output
{{name}}
My expected output is
Parshuram
Please can anyone help i am stuck at this point,does that $sce does not bind scope variable?? ..
I've created a working plnkr here: https://plnkr.co/edit/uOdbHjv1B7fr0Ra1kXI3?p=preview
the problem is that ng-bind-html is not bound to the scope.
you should manually compile the content.
a valid and reusable solution should be creating a directive, whitout using any external modules.
function compileTemplate($compile, $parse){
return {
link: function(scope, element, attr){
var parsed = $parse(attr.ngBindHtml);
function getStringValue() { return (parsed(scope) || '').toString(); }
scope.$watch(getStringValue, function() {
$compile(element, null, -9999)(scope);
});
}
}
}
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml" compile-template></div>
</div>
ng-bind-html does what it says on the tin: it binds html. It doesn't bind angular template code into your dom.
You need to do this instead:
$scope.thisCanBeusedInsideNgBindHtml =
$sce.trustAsHtml("<div>"+$sanitize(name)+"</div>");
To do this you'll want to include the module ngSanitize from the javascript angular-sanitize.js. See https://docs.angularjs.org/api/ngSanitize
If you want to insert some html that includes angular directives then you should write your own custom directive to do it.
In your html just use
{{name}}
The {{var}} notation is to be used in the HTML code to evaluate that variable.
You can do :
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml('<div ng-bind="name"></div>');
Sorry I make another answer.
If you have
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Then you can do
var str = "<div>{{name}}</div>";
var output = str.replace('{{name}}', $scope.name);
It seems to be the only option.

angular2 custom directives inputs syntax

I create a custom directive and set the selector value to be "[unless-directive]".
The directive get a Boolean and use it to change the view as so:
import {Directive, TemplateRef, ViewContainerRef} from 'angular2/core';
#Directive({
selector: '[unless-directive]',
inputs: ['givenBoolean : myDirectiveFunction']
})
export class UnlessDirective {
private _templateRef: TemplateRef;
private _viewContainerRef: ViewContainerRef;
constructor(_templateRef: TemplateRef, _viewContainerRef: ViewContainerRef) {
this._templateRef = _templateRef;
this._viewContainerRef = _viewContainerRef;
}
set myDirectiveFunction(condition: boolean) {
!condition ? this._viewContainerRef.createEmbeddedView(this._templateRef)
: this._viewContainerRef.clear();
}
}
In my template I tried to pass the condition like so:
<div name="customDirective">
<h2>Custom Directive</h2>
<div>
Enter true or false:
<br/>
<input type="text" #condition (keyup)="0"/>
<div *unless-directive [givenBoolean]="condition.value != 'false'">
Only shown if 'false' wad enterded!
</div>
</div>
</div>
When I running the code I get this error:
EXCEPTION: Template parse errors: Can't bind to 'givenBoolean' since
it isn't a known native property (" ... Only shown if 'false' wad enterded!"): StructualDirectivesComponent#47:39
I guess my syntax is wrong, but I can't find where or why?
I looked it up on Angular2 Docs, but the example use the same name for the input and the selector, the thing that I'm trying to avoid.
Can anyone know a better way or can find my syntax problem?
Thanks.
The * prefix syntax is only a syntatic sugar. It expands the directive declaration.
The * prefix syntax is a convenient way to skip the <template> wrapper tags and focus directly on the HTML element to repeat or include. Angular sees the * and expands the HTML into the <template> tags for us.
This is documented in * and <template> and Directive decorator/Lifecycle hooks.
So, in your case, the [givenBoolean] property is not expected to be in the directive. In other words, this:
<div *unless-directive [givenBoolean]="condition.value != 'false'">
Only shown if 'false' wad enterded!
</div>
Becomes, actually:
<template [unless-directive]="">
<div [givenBoolean]="condition.value != 'false'">
Only shown if 'false' wad enterded!
</div>
</template>
And since givenBoolean is not a property in the component (not the directive), the error appears.
So if you want custom behavior, I suggest you experiment using the expanded version and only after it works you go to the * syntax, it will be simpler to reason about.

Angular js - simple loop on json object

Hi there i'm trying prnting a simple json object to a div:
<div ng-repeat=" i in config.app_genres.genres">
{{ i }}
</div>
and
config.app_genres = {
"genres":["asd","ips"]
}
what's wrong with this?
Also how can i log config.app_genres in a view?
Have a look at this plunk.
As for logging config.app_genres in the view, not sure what you mean, care to elaborate?