Angular run only one of two functions - html

Is that possible to have two functions inside HTML element but to run only one of them according to a condition? for example:
<Button (click)="aFunction() ? anotherFucntion()">Hi</Button>

i think you want someThing Like This
export class AppComponent {
someFlag: boolean = false;
firstFunction() {
console.log('hi i am from first Function');
}
secondFunction() {
console.log('hi i am from Second Function');
}
}
<button (click)="someFlag ? firstFunction() : secondFunction()">Hi</button>
but i would prefer if the code in the Component Like This
doTheWork() {
return this.someFlag ? this.firstFunction() : this.secondFunction();
}
and then just call it in the html Like this
<button (click)="doTheWork()">Hi</button>
you can test the code here

Related

Using 2 Pages to filter a table in angular

I'm quite new to angular and wanted to know how to make it so i can have 1 page that you put the info you want to filter in the table and when you press "search" it will lead you to the second page where you see the table after its filtered.
i my question is odd but i really couldn't find any answer how to do this online.
I cant share code as its confidential to my work.
Something that looks like this site : https://maerskcontainersales.com/
I have tried using mock data but still couldn't put my head into the right thing to do.
There can be multiple ways how you can achieve this.
Using Provider
Suppose you have two pages and , serach-page is where you will enter your filters and result-page is where the table renders.
In search-page, you will create inputs( ex: textbox, dropdown etc ) and have ngModels for all of them, or you can use Angular reactive forms i.e FormGroup and FormControls. Users will select their input and click on search button, which will read values from models or controls and store them in the provider.
search-page.component.html
<form [formGroup]="searchForm" (submit)="search()">
<input formControlName="country" />
<input formControlName="city" />
...
<input type="submit">
</form>
search-page.component.ts
export class SearchPage {
...
search() {
const country = this.searchForm.get('country').value
...
// get rest of the values
...
this.searchService.setData({ country, city });
this.router.navigate(['/result']); // '/result' is path on the result-page
}
...
}
search.service.ts
#Injectable()
export class SearchService {
_data : any;
set data(val) {
this._data = val;
}
get data() {
return this._data;
}
}
result-page.component.ts
export class ResultPage {
...
ngOnInit() {
const filters = this.searchService.getData();
// filters will be your data from previous page
}
...
}
Using RouterParams
search-page.component.html
// same as before
search-page.component.ts
export class SearchPage {
...
search() {
const country = this.searchForm.get('country').value
...
// get rest of the values
...
this.router.navigate(['/result', { country, city }]); // '/result' is path on the result-page
}
...
}
result-page.component.ts
export class ResultPage {
...
constructor(route:ActivatedRoute) {
this.country = route.snapshot.paramMap.get("country")
// alternatively you can also do below
route.paramMap.subscribe(filters => {
// you will have your filters here
});
}
...
}
And once you have values of filters in result-page, use them to get data or filter data if already fetched, then render the table accordingly.
Let me know if I wasn't clear.
The simple solution I would suggest you to use a filter component and a results component a third container component. This component will get the filter criteria as an input variable and will output the filter criteria (using an output variable) when you press the "filter" button.
The container app will look like this:
<filterComponent (onFilter)="changeFilter($event)" [data]="someDate" *ngIf="!filterCriteria"></filterComponent>
<resultsComponent [data]="someDate" [filterCriteria]="filterCriteria" *ngIf="!!filterCriteria"></resultsComponent>
The filterCriteria that is sent to the second tableComponent will come from the eventEmmiter of the first tableComponent. The filterCriteria variable will be initiate to null and this will allow you to switch from one table to the other.

(click) event not work in innerHtml string Angular 4

My function isn't called when I click the <a... tag.
I have the following code in my component:
public htmlstr: string;
public idUser:number;
this.idUser = 1;
this.htmlstr = `<a (click)="delete(idUser)">${idUser}</a>`;
public delete(idUser){
alert("id " + idUser);
}
My html
<div [innerHTML]="htmlstr"></div>
but the function delete isn't called and does not show the alert.
The <div... is created dynamically
If anyone face same issue and above all answer not working then try my trick :
In HTML :
<button onclick="Window.myComponent.test()"> test </button>
In component :
class
constructor(){
Window["myComponent"] = this;
}
test(){
console.log("testing");
}
Your main issue here, on-top of the things pointed out by #Matt Clyde and #Marciej21592, is that you're trying to dynamically add HTML code that needs to be compiled before it can be used (you're trying to bind to a method and variable).
Some ways of doing this can be seen here.
From the code you have supplied, however, there are much easier ways to accomplish what you are after. For starters, I would have that code in the HTML to begin with and hide/show it as needed with ngIf.
i use this method and its work
public htmlstr: string;
public idUser:number;
this.idUser = 1;
this.htmlstr = `<a id='innerHtmlClick'>${idUser}</a>`
this.htmlstr.querySelector(`innerHtmlClick`).addEventListener('click', () => {
this.delete(idUser);
});
public delete(idUser){
alert("id " + idUser);
}
EventListener listen the event bye using id of innerHtml
I assume that it is not a bug but rather Angular's security measure against XSS attacks - for more information I would suggest taking a look here https://angular.io/guide/security#sanitization-example
I somewhat also fail to understand why you insist on passing the event via string literal instead of just simply using:
<div>
<a (click)="delete(idUser)">${this.idUser}</a>
</div>
Your component has inner Html.
Angular will not allow events inside inner Html portions for security reasons. You can use Child components. to make events from inside of inner Html portions. Create a child component and put your html inside the child component and pass the data by using any angular events between parent and child using Input, Output features in Angular
I don't often use [innerHTML], but it looks like the template string you're using <a (click)="delete(idUser)">${idUser}</a> is referencing ${idUser} when you might have meant ${this.idUser}?
Below code snippet worked for me:-
In component :
ngAfterViewChecked () {
if (this.elementRef.nativeElement.querySelector('ID or Class of the Html element')) {
this.elementRef.nativeElement.querySelector('ID or Class of the Html element').addEventListener('click', this.editToken.bind(this));
}
}
inside constructor parameter:-
constructor( private readonly elementRef: ElementRef) {}
import { ElementRef } from '#angular/core';---> at the top of the file
implement 'AfterViewChecked'

Angular 5 - Auto-reload the HTML page of the specific component at some fixed intervals

The manual solutions for Auto Reloading the HTML page of a specific component:
Either by navigating to the HTML page on click.
Or calling the ngOnInit() of that component on click.
I am doing it manually using a click event from the HTML code as follows:
HTML Code: app.component.html
<button (click) = reloadPage()>
TS Code: app.component.ts
reloadPage() {
// Solution 1:
this.router.navigate('localhost:4200/new');
// Solution 2:
this.ngOnInit();
}
But I need to achieve this automatically. I hope I am clear. The page should auto-reload after some specific interval and call the ngOnInit() on each interval.
Add correct call to setInterval anywhere in your call:
setInterval(() => reloadPage(), 150000); and inside the method reloadPage put the same logic you have for the button.
An example:
Just put the reloadPage function call inside the constructor:
export class SomeComponent {
constructor() {
setInterval(() => this.reloadPage(), 150000);
}
reloadPage() {
// anything your button doeas
}
}
also note, that correct call of setInterval would be:
setInterval(() => this.reloadPage(), 150000);
Note: My answer just fixes the code you presented. But it seems there is some bigger logical misunderstanding of "reloading page" in angular and using ngOnInit

Function call on ngClass not working

I have a problem with a ngClass and a function with building an app with Ionic 2 and Firebase.
The function does work, but the value of the function does not come in the HTML code. I have used this as an example: https://codepen.io/andre13/pen/oecgi.
The html and the call for the function looks like this:
<button ion-button class="chatbutton" [ngClass]="compareUser(user.$key)"
(click)="gotoDoctorChat(user.$key)" >{{user.naam}} </button>
The function looks like this:
compareUser(uid){
this.angFire.database.object('/users/' + uid +'/'+ this.coach1+'red').subscribe(snapshot=>{
console.log("snapshot.tostring = " + snapshot.$value);
if(snapshot.$value === '0'){
return 'unread';
}else{
return null;
}
})
};
The CSS looks like this:
.unread{
background-color: red!important;
}
Please ask if something is not clear.
Try enclosed by single quote (') like this
return "'unread'";
and also make sure you have imported the correct module in the main component
import { NgClass } from '#angular/common';
The reason is because function compareUser always returns undefined before the internal function call is resolved.
You can test this with:
console.log(compareUser(aUID));
Difficult to suggest an alternative without knowing more of your logic/requirements.

How to show translation text in angularjs controller alert from json file?

I have a JSON file with translations, like this one:
"ALERT_MESSAGE" : "Select a row"
Now, I want to show an alert from my controller when the user try to access to a link without select a row.
$scope.goToNext = function () {
if($scope.isSelected === false){
alert("What should I put here?");
}
else{
Navigator.goTo("/next", {
back: "/previus",
asd: $scope.asd
});
}
};
How can I use my translations file on the controller?
Another possibility is using the $translate service itself (if you are using angular-translate ;))
alert($translate.instant('ALERT_MSG'));
Finally adding $filter to the controller and using it like here:
alert($filter('translate')('ALERT_MSG'));
Following function will show the changed language:
$scope.translateLangText=function(text){
$scope.$watch(
function() { return $filter('translate')(text); },
function(newval) { alert(newval); }
);
}
$scope.translateLangText('Hello');