I'm writing a code where when you click a button of an item, a side pannel opens, and you can see some data in it. I'm currently getting the error below when I click the preview button. Furthermore, I could not figure out the problem. What can be the problem?
Main Screen HTML:
<button mat-icon-button matTooltip="Preview" class="sidebar-toggle"
(click)="openSidebar('sticker-preview-sidebar', row.StickerData)">
<mat-icon>pageview</mat-icon>
</button>
<fuse-sidebar class="sidebar centra details-sidebar fuse-white" name="sticker-preview-sidebar" position="right">
<sticker-preview [StickerData]="previewStickerData"></sticker-preview>
</fuse-sidebar>
Main Screen TS:
previewStickerData: IStickerData;
openSidebar(name: string, stickerData: IStickerData): void {
this.previewStickerData = stickerData;
this._fuseSidebarService.getSidebar(name).open();
}
Side Bar HTML:
<div class="content fuse-white ml-24 mr-8 h-100-p" fusePerfectScrollbar>
<div class="label-list">
<p>
Sticker Info
<span>{{stickerData.StickerData}}</span>
</p>
</div>
Side Bar TS:
private _stickerData: IStickerData;
#Input()
set StickerData(prm: IStickerData) {
if (this._stickerData != prm) {
this._stickerData = prm;
}
}
get StickerData(): IStickerData {
return this._stickerData;
}
dataSource: MatTableDataSource<IStickerData>;
constructor(
private _router: Router,
private _fuseSidebarService: FuseSidebarService,
private _productionService: ProductionService) {
}
Related
when i open my website i will see "Finance/voucher" on topenter image description here but when i refresh the page only "Finance" Appears and i don't want this i want when i refresh page still it will show "Finance/voucher" And all relevant code i have posted plz guide me which code i enter and where
export class TopBarComponent extends AppComponentBase {
formName = ""
constructor(
injector: Injector,
private _formTitleService: FormTitleService,
) {
super(injector);
}
ngOnInit() {
this.getFormTitle();
}
getFormTitle(){
this._formTitleService.getFormTitle()
.subscribe(name => {
this.formName = name;
});
}
Html code
<div class="page-title">
/ <span>{{formName}}</span>
</div>
You can set the initial value for formName = "Finance/voucher" in your component & it will be retained on page refresh.
I'm using Angular 9, where I want to dynamically change data of a menu item when a person logs in. But instead, since the menu gets loaded along with the home page, when a person logs in, the data change is not reflected in the menu items until I refresh the page manually. I tried using Renderer 2, ChangeDetectorRef and ElementRef but failded to reload the menu automatically. Below I'm adding just the relevant elements since the actual component code is long. Ask me if you need to know anything else:
Html:
<div class="widget-text">
<a mat-button [matMenuTriggerFor]="accountMenu" #accountMenuTrigger="matMenuTrigger" *ngIf="!isLoggedIn">
<mat-icon>person</mat-icon>
<span fxShow="false" fxShow.gt-sm class="flag-menu-title">Account</span>
<mat-icon class="mat-icon-sm caret cur-icon">arrow_drop_down</mat-icon>
</a>
<mat-menu #accountMenu="matMenu" [overlapTrigger]="false" xPosition="before" class="app-dropdown">
<span>
<button mat-menu-item [routerLink]="['/admin/login']" routerLinkActive="router-link-active">
<mat-icon >person</mat-icon>
<span>Login</span>
</button>
<button mat-menu-item [routerLink]="['/admin/login']" routerLinkActive="router-link-active">
<mat-icon>person_add</mat-icon>
<span>Register</span>
</button>
</span>
</mat-menu>
<a mat-button [matMenuTriggerFor]="profileMenu" #profileMenuTrigger="matMenuTrigger" *ngIf="isLoggedIn">
<mat-icon>person</mat-icon>
<span fxShow="false" fxShow.gt-sm class="flag-menu-title">Howdy, {{name}}</span>
<mat-icon class="mat-icon-sm caret cur-icon">arrow_drop_down</mat-icon>
</a>
<mat-menu #profileMenu="matMenu" [overlapTrigger]="false" xPosition="before" class="app-dropdown">
<span>
<button mat-menu-item [routerLink]="['/admin/profile']" routerLinkActive="router-link-active">
<mat-icon >person</mat-icon>
<span>Profile</span>
</button>
<button mat-menu-item (click)="logout()">
<mat-icon>warning</mat-icon>
<span>Logout</span>
</button>
</span>
</mat-menu>
</div>
typescript:
public name;
public isLoggedIn = false;
constructor(public router: Router, private cartService: CartService, public sidenavMenuService:SidebarMenuService) {
this.checkLogin();
this.name = Cookie.get('userName');
}
public checkLogin(): any {
if(Cookie.get('authtoken')) {
this.isLoggedIn = true;
}
}
You don't need to make things complicated, when you logged in your logged in guard (i.e. auth guard).
import { Injectable } from '#angular/core';
import { Router, CanActivate } from '#angular/router';
import { AuthService } from './auth.service';
#Injectable()
export class AuthGuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router , private sideMenuService: SideMenuService) {}
canActivate(): boolean {
if (!this.auth.isAuthenticated()) {
this.sideMenuService.sideMenuData.next({...data}); // so here you can dispatch the side menu service data .
this.router.navigate(['dashboard']); // here after authentication it
will redirect to your dashboard
page
return false;
}
return true;
}
}
}
so after redirect when you land on the Dashboard Page , in the Dashboard component you have also inject the sideMenu Service and subscribe the BehaviourSubject menu data field .
public name;
public isLoggedIn = false; // here you don't need to check login
// because you come here from auth guard
constructor(public router: Router, private cartService: CartService,
public sidenavMenuService: SidebarMenuService) {
this.checkLogin(); // same no need to check login in each
component if you use auth guard
this.name = Cookie.get('userName');
}
public ngOnInit(){
this.sideMenuService.sideMenuData.subscribe((data)=>{
// hered you get the data dynamic , you can assign to any
// component field.
});
}
public checkLogin(): any {
if(Cookie.get('authtoken')) {
this.isLoggedIn = true;
}
}
so that's how whenever you login every time you dispatch some dynamic data and your behaviourSubject will get updated and where ever you subscribe like in Dashboard component you will get the dynamic data.
Hope it will help.
The constructor is executed only one time during the creation of the page.
constructor(public router: Router, private cartService: CartService, public sidenavMenuService:SidebarMenuService) {
this.checkLogin();
this.name = Cookie.get('userName');
}
Now, according to the code, if the cookie authtoken is not found during the construction, there is no way your app to know if that was created by another (login) process.
You should call the checkLogin function and the name assignment right after your login cocmpletes.
I am making a to-do application in Angular. Right now I have the add/delete/edit functionality working but I have to refresh the web page every time to see the changes occur.
I want it so that once a to-do list item is added, the user can see the item added to the list automatically without having to refresh the page every time. Same goes for deleting and editing the items.
This is my HTML below:
<div>
<input type="text" value={{toDoItem}} [(ngModel)]="toDoItem">
<button (click)="addToDo()">Add to List</button>
</div>
<div class="items" *ngFor="let todo of todoList">
<div >
<input type="checkbox" [(ngModel)]="todo.completed" (change)="updateCompleted(todo.id)">
<div *ngIf="!todo.editing; else editingTodo">{{ todo.content }}</div>
<ng-template #editingTodo>
<input #editVal type="text" value={{updatedItem}} [(ngModel)]="todo.content" >
<button (click)="onEdit(todo.id, editVal.value)">Save</button>
<button (click)="toggleEdit(todo.id)">Cancel</button>
</ng-template>
</div>
<div class="remove-item">
<button (click)="removeTodo(todo.id)">Remove</button>
<button (click)="toggleEdit(todo.id)">Edit</button>
</div>
</div>
And here is my typescript file with the logic below:
export class ToDoListComponent implements OnInit{
#Input()
todo: Todo;
toDoItem: string;
updatedItem: string;
todoList: Todo[];
show = false;
constructor(private todoService: ToDoService) {
this.toDoItem = '';
this.updatedItem = '';
}
ngOnInit() {
this.todoList = this.todoService.getTodos();
}
addToDo() {
this.todoService.addTodo(this.toDoItem);
this.toDoItem = '';
}
removeTodo(id: number) {
this.todoService.removeTodo(id);
}
updateCompleted(id: number) {
this.todoService.updateComplete(id);
}
toggleEdit(id: number) {
this.todoService.toggleEdit(id);
}
onEdit(id: number, newContent: string) {
this.todoService.editTodo(id, newContent);
this.todoService.toggleEdit(id);
}
}
Basic mistake is component is not maintaining the state instead todoService is.
So Mistake : inside ToDoListComponent todoList have been initialized only once, at ngOnInit lifecycle hook.
Solution : in addToDo method after pushing value to todoService, call below line again,
this.todoList = this.todoService.getTodos();
Same should be done for update and delete to see the changes reflected for those operations.
I have a simple search method inside a component that updates an array to satisfaction. When the array is updated however, the list that should appear in the html page simply does not.
Here is my TypeScript:
export class AccommodationOverviewComponent implements OnInit {
private resultMessage: string;
private city: string;
private inputvalue: string;
accommodations: Array<Accommodation> = [];
constructor(private accommodationService: AccommodationService, private router: Router, private route: ActivatedRoute, private changeDetection: ChangeDetectorRef) { }
ngOnInit(): void {
}
getAllAccommodations()
{
this.accommodationService.getAllAccommodations()
.subscribe(
data => {
console.log(data);
this.accommodations = data;
},
error => {
console.log(error);
this.resultMessage = "Something went wrong";
});
}
searchByCity(){
this.city = (<HTMLInputElement>document.getElementById("searchbarCity")).value;
this.accommodationService.getAccommodationByCity(this.city)
.subscribe(
data => {
console.log(data);
this.accommodations = data;
console.log(this.accommodations);
this.changeDetection.detectChanges();
},
error => {
console.log(error);
this.resultMessage = "Something went wrong"
}
)
}
}
and here the HTML:
<div class="row">
<div class="col">
<div class="header-text">
<h1>Find the desired accommodation</h1>
</div>
</div>
</div>
<div class="form-row">
<div class="form-input">
<label>Enter the city in which you want to find accommodations.</label>
<input id="searchbarCity" type="text" value="" (submit)="searchByCity()"/>
<button (click)="searchByCity()">Search</button>
</div>
</div>
<div class="form-row">
<div class="form-input">
<tr *ngFor="let accommodation of accommodations">
{{accommodation.Country}}
{{accommodation.City}}
{{accommodation.StreetandNumber}}
{{accommodation.PostalCode}}
{{accommodation.Size}}
{{accommodation.PeopleAllowed}}
{{accommodation.PrizePerNight}}
{{accommodation.Roof}}
{{accommodation.Ground}}
{{accommodation.OwnerId}}
</tr>
</div>
</div>
I am aware that most people get their data in onInit but I only want to update my array after a search request is made so the user does not have to hold an enormous set of data mostly seen in the getall method. As this is for a project with a large user base as criteria.
I want to update the HTML page list when the data array in the typescript changes. I only want to receive this data after a search request is made (which it does perfectly).
Is this possible at all and if so what am I doing wrong?
I have a page in which I have a Run button.If I click on Run button a dialog box appears with two options Yes and No.If a user clicks Yes I want to display a mat-progress bar.
I am confused as to where to write the html code of mat-progress bar and where to call it from.
HTML Code:
<mat-toolbar>
<div class="col-md-offset-11">
<button
mat-raised-button
mat-hint="Execute Query on Whole DataSet"
color="primary"
(click)="executeOnFullData()"
>
Run
</button>
</div>
</mat-toolbar>
TypeScript Code:
executeOnFullData() {
const dialogRef = this.dialog.open(ConfirmJobRunComponent, {
});
dialogRef.afterClosed()
}
HTML Code for dialogBox:
<div class="card">
<div class="card-header"><h5 class="title">Confirm</h5></div>
<div class="content">
<h3 mat-dialog-title>
Are you sure you want to run Recommendation Settings on the entire
Dataset?
</h3>
<div mat-dialog-actions>
<button
mat-button
[mat-dialog-close]="true"
(click)="confirmSelection()"
>
Yes
</button>
<button mat-button (click)="onNoClick()">
Cancel
</button>
</div>
</div>
Typescript Code for DialogComponent
import { MAT_DIALOG_DATA, MatDialogRef } from "#angular/material";
import { Component, Inject } from "#angular/core";
import { RecommendationService } from "../../recommendation-
service.service";
#Component({
selector: "app-confirm-job-run",
templateUrl: "./confirm-job-run.component.html",
styleUrls: ["./confirm-job-run.component.scss"]
})
export class ConfirmJobRunComponent {
constructor(
public dialogRef: MatDialogRef<ConfirmJobRunComponent>,
#Inject(MAT_DIALOG_DATA) public data: any,
public dataService: RecommendationService
) {}
onNoClick(): void {
this.dialogRef.close();
}
confirmSelection(): void {}
}
You can just subscribe to afterClosed of your dialogRef and based on the result you get back from your dialog (clicking Yes returns true, clicking No returns false) you can then show a mat-progress and execute your business logic.
Here
is a stackblitz showing how this could look like. The mat-progress
is currently indeterminate and not waiting for something to complete,
that is up to you.
Template (in your component where the button is located)
<mat-progress-bar *ngIf="showMatProgress" mode="indeterminate"></mat-progress-bar>
Component for above template
showMatProgress: boolean = false;
executeOnFullData() {
const dialogRef = this.dialog.open(ConfirmJobRunComponent, {});
dialogRef.afterClosed().subscribe((result) => {
this.showMatProgress = result;
});
}
An in your dialog component
onNoClick(): void {
this.dialogRef.close(false);
}
confirmSelection(): void {
this.dialogRef.close(true);
}