how to update the fields from post method in angular? - javascript

I want to update the field by clicking the submit from matdialog .
html
<h2>network <mat-icon (click)="openDialog(mytemplate)">add_circle_outline</mat-icon></h2>
<ng-template #mytemplate>
<div class="container">
<div class="box">
<mat-form-field appearance="outline">
<input matInput placeholder="enter the items" />
</mat-form-field>
<button mat-stroked-button mat-dialog-close color="accent">CANCEL</button>
<button mat-flat-button color="accent" (click)="onclick()">Submit</button>
</div>
</div>
</ng-template>
.ts
provider = [];
providers: provider;
getnetwork() {
this.service.getAllNetworkProviders().subscribe(res => {
this.provider = res.data;
this.dataSource = this.provider;
});
}
openDialog(template): void {
// ask user to confirm, if he really wants to proceed
this.dialogRef = this.dialog.open(template);
this.dialogRef.afterClosed().subscribe(isTrue => {
if (isTrue) {
const activatenetworkprovider = { networkName: this.providers.id };
this.service.networkProviderStatus(activatenetworkprovider).subscribe(data => {
this.getnetwork();
this.snackBar.open('Successfully created new network provider sim', 'Close', { duration: 2000 });
});
}
});
}
model.ts
export interface provider {
id: number;
name: string;
}
I'm getting error [ERROR TypeError: Cannot read properties of undefined (reading 'id')
].
I have updated the questions .

This is a declaration:
providers: provider;
It is not an actual object/instance, but rather just a handle to an object. You still need to assign something to this with =. Preferably an object that contains a member id (e.g.: { id: 1, ... }).
It is also convention to name interfaces with capital letters, like this:
export interface Provider {
id: number;
name: string;
}

Related

How can I add and remove specific data in local storage?

I started learning Angular recently, I'm trying to make a github search app with the github api but I have some problems with local storage. I have an add to favorite button for pin the profile to the page. When it's pinned remove favorite button should be appear instead of add to favorite button and it should be remove the profile. I thought I could do this with adding and removing profiles from local storage. I have an user variable which holds the profile info as an object when the user types username in the search bar. Then I'm passing this data to local storage and take all the local storage data to make it an array so I can display it with *ngFor. The problem is when I pin the profile, I can't remove permanently specific profile from the page. I can only delete pinned profiles temporarily. I'm dealing with this problem for two days, I have shared the part what I did until now. The purple area is where the pinned profiles are shown.
home.component.html:
<input type="text" [(ngModel)]="profile" (ngModelChange)="detectChange($event)" (keyup)="findProfile()" placeholder="Enter the username..." class="input">
<div style="background-color: lightslategrey;">
<ng-template [ngIf]="profile !== '' && user">
<img [src]="user.avatar_url" alt="" class="userAvatar">
<p>Username: {{user.login}}</p>
<p>Location: {{user.location}}</p>
<p>E-mail: {{user.email}}</p>
<p>Blog Link: {{user.blog}}</p>
<p>Member Since: {{user.created_at}}</p>
<button [routerLink]="['', user.login.toLowerCase(), user.id ]" class="viewProfileButton" a>View
Profile</button><br>
<button (click)="localStorage()" class="viewProfileButton">Add to Favorite</button>
</ng-template>
</div>
<div style="background-color: rgb(106, 106, 170);" *ngFor="let item of display">
<button (click)="consoleLog()">consoleLog</button>
<p>Username: {{item.login}}</p>
<p>Location: {{item.location}}</p>
<p>ID: {{item.id}}</p>
<button (click)="localStorage(item.id)">Add to favoriteeee</button>
<button (click)="removeLocal(item.id)" class="viewProfileButton">Remove Favorite</button>
</div>
<button (click)="consoleLog()" class="viewProfileButton">Console Log</button>
<router-outlet></router-outlet>
home.component.ts:
import { Component, OnInit, Input } from '#angular/core';
import { HttpService } from '../http.service';
import { ProfileComponent } from './profile/profile.component';
import { JsonPipe } from '#angular/common';
import { bindCallback } from 'rxjs';
import { FormArray } from '#angular/forms';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
})
export class HomeComponent implements OnInit {
user: any;
profile: any;
display: any;
local: any;
randomNumber: any;
randomString: any;
idString: any;
keys: any;
closeDiv: boolean = true;
constructor(private userData: HttpService) {}
ngOnInit() {
this.display = Object.values(localStorage).map((val: any) => JSON.parse(val));
console.log('ngOnInit Works', this.display);
}
findProfile() {
this.userData.updateProfile(this.profile);
this.userData.getUser().subscribe((result) => {
this.user = result;
});
}
localStorage(id: any) {
this.idString = JSON.stringify(id);
localStorage.setItem(this.idString, JSON.stringify(this.user));
this.display = Object.values(localStorage).map((val: any) => JSON.parse(val));
console.log(Object.values(this.display));
}
removeLocal(id: any) {
for (let i = 0; i < this.display.length; ++i) {
if (this.display[i].id === id) {
this.display.splice(i, 1);
localStorage.removeItem(this.display[i].id);
}
}
}
detectChange(ev: any) {
ev.length > 0 ? (this.closeDiv = false) : (this.closeDiv = true);
}
}
in component.ts
let item = 1;
`
localStorage.setItem('itemName',Item);
const getItem = localStorage.getItem('itemName')
so constant getItem will have your value. you can do the same with an array

EditSensorComponent.html:10 ERROR TypeError: Cannot read property 'name' of undefined

I have a problem when I get to the edit route. I get this message -
ERROR TypeError: Cannot read property 'name' of undefined
When I comment input name error comeback for the next input. Looking my code.
import { Component, OnInit } from '#angular/core';
import { SensorService } from '../servicesapi/sensor.service';
import { ActivatedRoute, Router } from '#angular/router';
import { ISensor } from '../sensor/sensor'
#Component({
selector: 'app-edit-sensor',
templateUrl: './edit-sensor.component.html',
styleUrls: ['./edit-sensor.component.scss']
})
export class EditSensorComponent implements OnInit {
id: number;
sens: ISensor;
constructor(private route: ActivatedRoute, private router: Router,
private
sensor: SensorService) { }
ngOnInit() {
// this.sens = new ISensor();
this.id = this.route.snapshot.params['id'];
this.sensor.getSingleSensor(this.id)
.subscribe(data => {
console.log("data" , data)
this.sens = data;
}, error => console.log(error));
}
updateEmployee() {
this.sensor.updateSensor(this.id, this.sens)
.subscribe(data => console.log(data), error => console.log(error));
// this.employee = new Employee();
// this.gotoList();
this.router.navigate(['/']);
}
onSubmit() {
this.updateEmployee();
}
}
Also my html showing error:
<h3>Update Employee</h3>
<div [hidden]="submitted" style="width: 400px;">
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" required
[(ngModel)]="sens.name" name="name"> //here is problem
</div>
<div class="form-group">
<label for="path">Path</label>
<input type="text" class="form-control" id="path" required
[(ngModel)]="sens.path" name="path">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
I can read the data. I can even startle them, but this error returns me.
The reason you're getting this error is because the EditSensorComponent's HTML file is rendered by the DOM before the ngOnInit(). Now, since you've only defined sens and not initialized it, you're getting an undefined error
Try this:
1. Initialize the sens object in the EditSensorComponent while you're defining it.
2. Looking at the code, I'm assuming the sens object has two properties (name and path)
sens: ISensor = {
name: '',
path: ''
}

How to check for state change in angular 4/6?

My task is to create an account information web page which consists of 4 pre-filled fields (given name, family name, username and email) and a common save button at the bottom. User can change any field by the respective field. I want save button to be enabled only if user changes any fields. Any method to track state changes? My code is as follows:
<mat-card-content>
<div class="form-group">
<mat-form-field class="simple-form-field-50">
<input matInput placeholder="Given name" name="givenName" formControlName="givenName">
</mat-form-field>
<mat-form-field class="simple-form-field-50">
<input matInput placeholder="Family name" name="familyName" formControlName="familyName">
</mat-form-field>
<br>
<mat-form-field>
<input matInput placeholder="Email" name="email" formControlName="email">
</mat-form-field>
<br>
<button
[disabled]="waiting"
class="simple-form-button"
color="primary"
mat-raised-button
type="submit"
value="submit">
Save
</button>
</div>
</mat-card-content>
My Code Output:
Since you're using a Reactive Form, you can use valueChanges on the FormGroup.
Since it is of type Observable, you can subscribe to it to set a variable of type boolean that will be used in the template to enable the button.
...
#Component({...})
export class AppComponent {
form: FormGroup;
disableButton = true;
ngOnInit() {
...
this.form.valueChanges.subscribe(changes => this.disableButton = false);
}
}
And in your template:
<form [formGroup]="form">
...
<button [disabled]="disableButton">Submit</button>
</form>
UPDATE:
If you want to disable it when values don't really change, check for the current value of the form with the previous value:
import { Component } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
form: FormGroup;
disableButton = true;
userValue = {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe#domain.com'
}
ngOnInit() {
this.form = new FormGroup({
firstName: new FormControl(),
lastName: new FormControl(),
email: new FormControl()
});
this.form.patchValue(this.userValue);
this.form.valueChanges.subscribe(changes => this.wasFormChanged(changes));
}
private wasFormChanged(currentValue) {
const fields = ['firstName', 'lastName', 'email'];
for(let i = 0; i < fields.length; i++) {
const fieldName = fields[i];
if(this.userValue[fieldName] !== currentValue[fieldName]) {
console.log('Came inside');
this.disableButton = false;
return;
}
}
this.disableButton = true;
}
}
NOTE: StackBlitz is updated accordingly.
Here's a Working Sample StackBlitz for your ref.
onChange(targetValue : string ){
console.log(targetValue );}
<input matInput placeholder="test" name="test" formControlName="testNM" (input)="onChange($event.target.value)">
This is called Dirty Check.
You may find this SO answer very useful:
https://stackoverflow.com/a/50387044/1331040
Here is the guide for Template-Driven Forms
https://angular.io/guide/forms
Here is the guide for Reactive Forms
https://angular.io/guide/reactive-forms
And here is the difference between two concepts
https://blog.angular-university.io/introduction-to-angular-2-forms-template-driven-vs-model-driven/
Hope these help.
I would do something like this:
form: FormGroup;
disableButton = true;
originalObj: any;
ngOnInit() {
this.form = new FormGroup({
control: new FormControl('Value')
});
this.originalObj = this.form.controls['control'].value; // store the original value in one variable
this.form.valueChanges.subscribe(changes => {
if (this.originalObj == changes.control) // this if added for check the same value
{
this.disableButton = true;
}
else {
this.disableButton = false;
}
}
);
}
WORKING EXAMPLE

Filter pipe not working Angular 5

I am trying filter data from firebase by user input. I have created a pipe to handle this but I keep getting the error:
ERROR TypeError: Cannot read property 'indexOf' of undefined
my html is:
<div class="container-fluid">
<div class="col-md-6">
<input class="search" type="text" placeholder="search proerties by post-code" [(ngModel)]="searchTerm">
</div>
<div class="row">
<div class="col-md-4" *ngFor="let property of properties | propertyFilter:searchTerm">
{{property.post_code}}
</div>
</div>
</div>
ts file as follows:
export class SearchPropertiesComponent implements OnInit {
public properties: PropertyModel[];
routing = environment.routing;
searchTerm: string;
constructor(private _property: PropertyManageService) {
this._property.getAllProperties().valueChanges().subscribe(properties => {
console.log(properties);
this.properties = properties;
})
}
ngOnInit() {
}
}
and finally my pipe:
#Pipe({
name: 'propertyFilter'
})
export class PropertyFilterPipe implements PipeTransform {
transform(properties: PropertyModel[], searchTerm: string): PropertyModel[] {
if(!properties || !searchTerm) {
return properties;
}
return properties.filter(property =>
property.post_code.indexOf(searchTerm) !== -1); //ERROR HERE
}
}
I have tried changing post_code to other fields within the object I am receiving but I am still having the same problem. I guess this means the information is never actually getting as far as this for it to be undefined?
Any suggestions?

Ensuring value entered into a form is displayed on the same page after button click

I am working on a Swiss Tournament Project, wherein I have to enter the tournament, which has to be displayed on the same page after I click on the Add Tournament Button.
This is my code for adding a tournament :
<div class="container tourct">
<div class="row">
<div class="input-group" align="center">
<form (ngSubmit) = "onCreateTournament(f)" #f="ngForm">
<div class="col-lg-12 input-group col-md-offset-6">
<input type="text" ngModel class="form-control" placeholder="Tournament Name" id="tourName" name="tname">
<span class="input-group-btn">
<button class="btn btn-secondary">Create Tournament </button>
</span>
</div>
</form>
</div>
</div>
<div class="container tble">
<div class="row">
<app-display-tournaments></app-display-tournaments>
</div>
</div>
</div>
The typescript file for the HTML is as follows:
export class HomeComponent implements OnInit {
tournaments:any = [
];
constructor(private tournamentService: TournamentService) { }
ngOnInit() {
}
onCreateTournament(form: NgForm) {
const tourName= form.value.tname;
this.tournamentService.createTournament(tourName);
}
}
This particular component makes use of a service which is injected. The code applicable for this component is as follows:
#Injectable()
export class TournamentService implements OnInit{
token: string = null;
tournaments = [];
constructor(private http: HttpClient,
private router: Router,
private authorizationService: AuthorizationService)
{}
ngOnInit(){
}
createTournament(name: string){
this.token = 'JWT ' + this.authorizationService.getToken();
const body = {
name
}
this.http.post('http://localhost:8000/tournament',
{
headers: new HttpHeaders().set('Authorization', this.token)
})
.subscribe(
response => {}
);
}
All the appropriate modules are imported.
The post to localhost:8000 does this:
exports.createTournament = (req, res) => {
let user_id = req.user.id;
let name = req.body.name;
if(name.length > 0 && name.length<=50){
tournament.create_tournament(user_id,name, function(result){
res.json({
"message": "Successfully created Tournament"
});
})
}
else{
res.json({
"message": "Tournament name should be between 1 to 50 charecters"
})
}
}
How should I proceed so that once I have entered the name of the tournament, it is displayed on the same page, instantly?

Categories