Data are not saved in database - javascript

I have api end point which save data to the database, post/comments/
when I test it in postman everything works perfect. but in front end data are saved but only id , the data I want to save from form input author and comment.
here is what is saved in database after a user submit the form inputs:
{
"_id": {
"$oid": "5b26c65ffecfe0047846677d"
},
"author": null,
"description": null
}
Here is component.ts :
import { Component, OnInit} from '#angular/core';
import { MoviesService } from '../movies.service';
import { RouterModule, Routes } from '#angular/router';
import {ActivatedRoute} from '#angular/router';
#Component({
selector: 'app-movie',
templateUrl: './movie.component.html',
styleUrls: ['./movie.component.scss']
})
export class MovieComponent implements OnInit {
movie: object;
review: {};
addreview: any;
addreviews: any[];
constructor(private router: ActivatedRoute, private moviesService: MoviesService) {
this.movie = [];
this.review = [];
this.addreview = [];
this.addreviews = [];
}
addReview(addreview: any): void {
if (!addreview) { return; }
this.moviesService.createReview(addreview)
.then(reviews => {
console.log(reviews);
this.addreviews.push(reviews.addreview);
});
}
ngOnInit() {
this.router.params.subscribe((params) => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.moviesService.getMovie(id)
.then(movie => {
this.movie = movie;
});
});
this.router.params.subscribe((params) => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.moviesService.getReview(id)
.then(review => {
console.log(review);
this.review = review;
});
});
}
}
Here is service.ts
export class MoviesService {
searchStr: string;
queryUrl = '/search/';
theatreUrl = '/theatre/';
moveUrl = '/movies/';
reviewUrl = '/comments/';
private apiUrl = 'http://localhost:8000';
constructor(private http: Http, private _jsonp: Jsonp) { }
createReview(review: string): Promise<any> {
return this.http.post(this.apiUrl + this.reviewUrl, review)
.toPromise()
.then(this.handleData)
.catch(this.handleError);
}
private handleData(res: any) {
const body = res.json();
console.log(body); // for development purposes only
return body.result || body || {};
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for development purposes only
return Promise.reject(error.message || error);
}
}
compo.html
<form (ngSubmit)="addReview(addreview)">
<div class="form-group movie-username">
<label for="author">Name:</label>
<input type="text" class="form-control movie-username_text" id="usr" [(ngModel)]="addreview.author" name="author">
</div>
<div class="form-group movie-textarea">
<label for="movie-textarea_label description">Do you like the movie? leave us a comment below</label>
<textarea class="form-control rounded-0"
id="movie-textarea_textarea" #description="ngModel" rows="10"
[(ngModel)]="addreview.description"
name="description"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Submitted data are not saved to the database what is wrong with my code? any help will be apreciated, thanks

Related

Angular removing elements from a list shared with a service

this problem is driving me crazy.
I have an array defined within a service, which is used in 3 other components:
This is the service, file products.service.ts (notice the product array of Products)
import { Injectable } from '#angular/core';
import { ​​HttpClient } from '#angular/common/http';
import { Product } from './../models/Product';
import { ProductForm, productFormToProduct } from './../models/ProductForm';
// #Injectable({
// providedIn: 'root'
// })
const apiUrl = 'http://localhost:3000/products';
#Injectable()
export class ProductsService {
public products: Product[] = [];
constructor(private http: HttpClient) {}
getProducts() {
return this.http.get(apiUrl)
}
deleteProduct(p: Product) {
// this.products = this.products.filter(prod => prod.id !== p.id);
const i = this.products.indexOf(p);
this.products.splice(i,1);
return this.http.delete(apiUrl + "/" + p.id)
}
storeNewProduct(pf: ProductForm) {
const idList = this.products.map((x) => {return x.id});
const i = Math.max(...idList) + 1;
const p = productFormToProduct(pf);
p.id = i;
this.products.push(p);
return this.http.post(apiUrl, p)
}
}
This is the component where i subscribe to getProducts, and fill the array (file products.component.ts):
import { Component, OnInit } from '#angular/core';
import { ProductsService } from '../../shared/services/products.service';
import { Product } from '../../shared/models/Product';
#Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.scss']
})
export class ProductsComponent implements OnInit {
products: Product[] = [];
searchText: string = "";
constructor(private productsService: ProductsService) {}
ngOnInit(): void {
this.productsService.getProducts()
.subscribe((data: Product[]) => {
this.productsService.products = data;
this.products = this.productsService.products;
})
}
}
And this is the component where i subscribe to deleteProduct (file product-card.component.ts):
import { Component, Input, OnInit } from '#angular/core';
import { ProductsService } from '../../services/products.service';
import { Product } from './../../models/Product';
#Component({
selector: 'app-product-card',
templateUrl: './product-card.component.html',
styleUrls: ['./product-card.component.scss']
})
export class ProductCardComponent implements OnInit {
constructor(private productsService: ProductsService) {}
ngOnInit(): void {
}
#Input() product: Product
public buttonDeleteFunction() {
this.productsService.deleteProduct(this.product).subscribe();
}
}
The problem is, when i click on some delete product button, i have this weird behaviour:
Before click:
After click:
Here is the products.component.html file:
<div class="products__header">
<h3 class="products__heading">
Listado de productos ({{ products.length }})
</h3>
<input
class="products__search"
placeholder="Buscador"
type="search"
[(ngModel)]="searchText"
/>
</div>
<p *ngFor="let p of products">{{ p.name }}</p>
<p>{{ products }}</p>
<div class="products__list">
<app-product-card
*ngFor="let p of products | filterNames: searchText"
[product]="p"
></app-product-card>
</div>
Why do i get the expected behaviour in only two of the four places where i use the products list?
I know i can use an Output to manually remove the item from the list when i click the button, but i have been told that services are used instead of Inputs/Outputs when i want to share between multiple components, so i'd rather not use an Output for this
When you use your approach with common data on service layer then a common pitfall is that Angular does not detect the changes that affect your component. In that case you must inform your component for those changes using an emmiter.
Use an emmiter on service
productUpdated :EventEmitter = new EventEmitter();
deleteProduct(p: Product) {
// this.products = this.products.filter(prod => prod.id !== p.id);
const i = this.products.indexOf(p);
this.products.splice(i,1);
this.productUpdated.emit(this.products);
return this.http.delete(apiUrl + "/" + p.id)
}
And then listen for that change ProductsComponent
export class ProductsComponent implements OnInit {
products: Product[] = [];
searchText: string = "";
constructor(private productsService: ProductsService) {}
ngOnInit(): void {
this.productsService.getProducts()
.subscribe((data: Product[]) => {
this.productsService.products = data;
this.products = this.productsService.products;
})
this.productsService.productUpdated.subscribe( (data) => {
this.products = data;
});
}

How to access a previous value from a two way binded form input control?

Given the form here, I would like to be able to Update data in a SQL Table. In order to create the SQL query needed to make this happen I'll have to pass in both the previous row's value and the new row's value to make the proper comparison.
Example SQL Update Statement:
UPDATE MyTable
SET column1 = new_value1, column2 = new_value2,
WHERE column1 = oldValue1 AND column2 = oldValue2
Since my input is using two way binding however, I always get the new value when trying to pass it to my SQL service. Is there a way to access the row's previous value prior to sending it for update?
Form HTML:
<form #updateRowForm="ngForm" class="update-row-form">
<table mdbTable #tableEl="mdbTable" class="table table-bordered
table-responsive-md table-striped text-center">
<thead>
<tr>
<th *ngFor="let head of loadedTableData[0] | keys;">{{head}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of loadedTableData; let i = index;">
<td *ngFor="let property of item | keys;"
class="form-group" #editRow>
<input #editRowProp mdbInput
[(ngModel)]="loadedTableData[i][property]"
(click)="updateValue(item)"
(ngModelChange)="changeValue($event, item)"
class="form-control"
[name]="property + '_' + i"
type="text">
</td>
<td>
<button type="button" mdbBtn class="btn btn-primary
rounded
btn-sm my-0"
(click)="updateRow(loadedTableData[i], item)">Update</button>
<hr>
<button type="button" mdbBtn class="btn btn-danger
rounded
btn-sm my-0" (click)="deleteRow(item)">Remove</button>
</td>
</tr>
</tbody>
</table>
</form>
Component TS file:
import { Component, OnInit, ViewChild, ViewChildren, QueryList, OnDestroy } from
'#angular/core';
import { SqlService } from '../services/sql.service';
import { MdbTablePaginationComponent, MdbTableDirective } from 'angular-bootstrap-md';
import { NgForm, FormGroup } from '#angular/forms';
import { Subscription, BehaviorSubject } from 'rxjs';
import { MatSnackBar } from '#angular/material';
import { SuccessComponent } from '../snackbar/success/success.component';
import { ErrorComponent } from '../snackbar/error/error.component';
import { ConfirmComponent } from '../snackbar/confirm/confirm.component';
#Component({
selector: 'app-data-table',
templateUrl: './data-table.component.html',
styleUrls: ['./data-table.component.scss']
})
export class DataTableComponent implements OnInit, OnDestroy {
#ViewChild(MdbTablePaginationComponent) mdbTablePagination:
MdbTablePaginationComponent;
#ViewChild(MdbTableDirective) mdbTable: MdbTableDirective;
#ViewChild('addRowForm') addRowForm: NgForm;
#ViewChildren('prop') addRowProps: QueryList<any>;
#ViewChild('editRowForm') editRowForm: NgForm;
#ViewChild('editRow') editRow: FormGroup;
public loadedTableData: any = [];
public previousTableData: any = [];
public displayedColumns: any = [];
public tableHasBeenLoaded = false;
public rowBeingEdited: BehaviorSubject<any> = new BehaviorSubject<any>({});
public rowPreviousValue: BehaviorSubject<any> = new BehaviorSubject<any>({});
public currentTableData: any = {};
public rowsAffected = 0;
public elements: string[] = [];
public previous: any;
private subscriptions: Subscription[] = [];
constructor(private sqlService: SqlService,
private snackBar: MatSnackBar) { }
public ngOnInit(): void {
this.subscriptions.push(
this.sqlService.tableHasBeenLoaded.subscribe(data => {
this.tableHasBeenLoaded = data;
}),
this.sqlService.tableHasBeenLoaded.subscribe(data => {
this.tableHasBeenLoaded = data;
}),
this.sqlService.currentTableData.subscribe(data => {
this.currentTableData = data;
}),
this.sqlService.rowsAffected.subscribe(data => {
this.rowsAffected = data;
})
);
}
public updateRow(newRowValue: any, previousRowValue: any): void {
// Both of these values are the same.
console.log(newRowValue, ' << initialRow');
console.log(previousRowValue, ' <<previousRowVal')
const updateData = {
previousRowValue,
newRowValue
};
this.subscriptions.push(
this.sqlService.updateTableData(updateData)
.subscribe((resp) => {
console.log(resp, ' << update response');
// this.sqlService.currentDataView.next(resp);
if (resp) {
this.snackBar.openFromComponent(ConfirmComponent, {
duration: 3000,
data: this.rowsAffected
});
}
})
);
}
public ngOnDestroy(): void {
for (const sub of this.subscriptions) {
sub.unsubscribe();
}
}
}
SQL Service TS:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { tap } from 'rxjs/operators';
import { Observable, BehaviorSubject } from 'rxjs';
import { ITableList } from '../interfaces/ITableList.interface';
#Injectable({
providedIn: 'root'
})
export class SqlService {
private uri = 'http://localhost:8080';
private headers = new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8' });
public currentDataView: BehaviorSubject<any> = new BehaviorSubject<any>([]);
public currentTableData: BehaviorSubject<any> = new BehaviorSubject<any>({});
public tableHasBeenLoaded: BehaviorSubject<any> = new BehaviorSubject<boolean>(false);
public rowsAffected: BehaviorSubject<number> = new BehaviorSubject<number>(0);
constructor(private http: HttpClient) { }
public updateTableData(updateData: any): Observable<any> {
const parsedData = JSON.parse(JSON.stringify(updateData));
if (updateData) {
return this.http.post(`${this.uri}/api/updateTableData`, parsedData).pipe(
tap(
response => {
this.rowsAffected.next(response.rowsAffected);
},
error => {
throw new Error(error);
}
)
);
}
}
}
hi create one more object(e.g prevValue) store value in it.that should be deepcopy not shallow copy.. use JSON.stringify and JSON.parse to copy value in object.
e.g In newValue object you store the new value, before assigning the new value, save newValue in prevValue, by this you will have prevValue,
like if you want first value than don't update preValue

Problem with login and HTTP POST in Angular

I trying to implements a login system in Angular App, but it redirects to the main view and saves an empty object into Local Storage no meters what I typed into the form, a correct or fake account email and password. It's my first real project and first time to making a login system. Uniformly I don't have permission to show real API here.
The Code:
login.component.html
<div class="content">
<div fxLayout="column" fxLayoutAlign="center center">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Dobrodošli!</mat-card-title>
</mat-card-header>
<mat-card-content>
<img class="logo" src="../../assets/dnevnimeni.svg" alt="">
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput type="email" placeholder="E-Mail" formControlName="email">
<mat-error *nfIf="">Unesite odgovarajući E-Mail</mat-error>
</mat-form-field> <br>
<mat-form-field>
<input matInput type="password" placeholder="Password" formControlName="password">
<mat-error *ngIf="">Unesite validan password</mat-error>
</mat-form-field> <br>
<button mat-stroked-button>Login</button>
</form>
</mat-card-content>
</mat-card>
</div>
</div>
login.component.ts
import { Component, OnInit } from '#angular/core';
import { FormBuilder, Validators, FormGroup } from '#angular/forms';
import { Router } from '#angular/router';
import { AuthService } from '../services/auth.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
submitted = false;
returnUrl: string;
error: {};
loginError: string;
constructor(
private fb: FormBuilder,
private router: Router,
private authService: AuthService
) { }
ngOnInit() {
this.loginForm = this.fb.group({
email: ['', Validators.required],
password: ['', Validators.required]
});
this.authService.logout();
}
get email() { return this.loginForm.get('email'); }
get password() { return this.loginForm.get('password'); }
onSubmit() {
this.submitted = true;
this.authService.login( this.email.value, this.password.value).subscribe((data) => {
if (this.authService.isLoggedIn) {
const redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/';
this.router.navigate([redirect]);
} else {
this.loginError = 'email or password is incorrect.';
}
},
error => this.error = error
);
console.log(this.authService.restaurant.email);
}
}
and auth.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '#angular/common/http';
import { throwError, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Restaurant } from '../models/Restaurant';
#Injectable({
providedIn: 'root'
})
export class AuthService {
loginUrl = 'xxxxxxxx';
errorData: {};
restaurant: Restaurant;
constructor(private http: HttpClient) { }
redirectUrl: string;
login(email: string, password: string) {
var postData = "email=" + email + "&password=" + password;
return this.http.post<Restaurant>(this.loginUrl, postData)
.pipe(map(restaurant => {
if (restaurant) {
localStorage.setItem('currentRestaurant', JSON.stringify(restaurant));
}
}),
catchError(this.handleError)
);
}
isLoggedIn() {
if (localStorage.getItem('currentRestaurant')) {
return true;
}
return false;
}
getAuthorizationToken() {
const currentRestaurant = JSON.parse(localStorage.getItem('currentRestaurant'));
return currentRestaurant.token;
}
logout() {
localStorage.removeItem('currentRestaurant');
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
}
// return an observable with a user-facing error message
this.errorData = {
errorTitle: 'Oops! Request for document failed',
errorDesc: 'Something bad happened. Please try again later.'
};
return throwError(this.errorData);
}
}
In the map function you don't return any value and try to transform in object the parameters that sends in the post request;
login(email: string, password: string) {
let postData = {email : email ,password :password};
return this.http.post<Restaurant>(this.loginUrl, postData)
.pipe(map(restaurant => {
if (restaurant) {
localStorage.setItem('currentRestaurant', JSON.stringify(restaurant));
return restaurant;
}
}),
catchError(this.handleError)
);
}
Your post data should be like var postData = {email : email ,password :password} , but you have described get request with query parameters.
Also saving data in observable data stream is bad practice. Each new subscriber triggers execution of this code again
if (restaurant) {
localStorage.setItem('currentRestaurant', JSON.stringify(restaurant));
}
postData should be the object instead of string. also check by console.log in isLoggedIn() method, what data localStorage.getItem('currentRestaurant') returns, if it has a value like "{}" or "null" it will return true in if statement.
isLoggedIn() {
if (localStorage.getItem('currentRestaurant')) {
return true;
}
return false; }

Angular 4 Firebase error message is not showing on first click

I am working on Firebase authentication with angular 4. I am trying to display the error messages but it is showing on the second click. In the console, it shows the error on the first click, but when I bind it to HTML component it shows the click on the second click. I am using the following auth service.
import { Injectable } from '#angular/core';
import { AngularFireDatabaseModule, AngularFireDatabase } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from "#angular/router";
import * as firebase from 'firebase';
#Injectable()
export class AuthService {
authState: any = null;
isLoggedIn: any;
error: any;
constructor(private afAuth: AngularFireAuth,
private db: AngularFireDatabase,
private router:Router) {
this.afAuth.authState.subscribe((auth) => {
this.authState = auth
});
}
// Returns true if user is logged in
get authenticated(): boolean {
return this.authState !== null;
}
// Returns current user data
get currentUser(): any {
return this.authenticated ? this.authState : null;
}
// Returns
get currentUserObservable(): any {
return this.afAuth.authState
}
// Returns current user UID
get currentUserId(): string {
return this.authenticated ? this.authState.uid : '';
}
emailLogin(email:string, password:string) {
return this.afAuth.auth.signInWithEmailAndPassword(email, password)
.then((user) => {
this.router.navigate(['/dashboard_home'])
this.isLoggedIn = this.authenticated;
})
.catch(error => {
this.error = error;
console.log(error)
});
}
// Sends email allowing user to reset password
resetPassword(email: string) {
var auth = firebase.auth();
return auth.sendPasswordResetEmail(email)
.then(() => console.log("email sent"))
.catch((error) => console.log(error))
}
//// Sign Out ////
signOut(): void {
this.afAuth.auth.signOut();
this.router.navigate(['/administrator'])
}
//// Helpers ////
private updateUserData(): void {
// Writes user name and email to realtime db
// useful if your app displays information about users or for admin features
let path = `users/${this.currentUserId}`; // Endpoint on firebase
let data = {
email: this.authState.email,
name: this.authState.displayName
}
this.db.object(path).update(data)
.catch(error => console.log(error));
}
}
My login.html page looks like that.
<div class="card-block">
<div class="alert alert-danger" role="alert" *ngIf="error">{{ error }}</div>
<form autocomplete="off" id="loginAdmin" (submit)="loginAdmin($event)">
<div class="row">
<div class="col-md-4 mx-auto">
<mat-form-field>
<input type="text" id="username" name="username" matInput placeholder="Användarnamn">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-4 mx-auto">
<mat-form-field>
<input type="password" id="password" name="password" matInput placeholder="Lösenord">
</mat-form-field>
</div>
</div>
<div class="row"></div>
<div class="row">
<div class="col-md-12 text-center">
<button type="submit" mat-raised-button>Logga in</button>
</div>
</div>
</form>
</div>
and my component.ts for login page is given
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../services/auth/auth.service';
import {Router} from "#angular/router";
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
error = '';
constructor(private authService: AuthService, private router: Router) { }
ngOnInit() {
}
loginAdmin(e) {
e.preventDefault();
var email = e.target.elements[0].value;
var password = e.target.elements[1].value;
if(email && password) {
var responses = this.authService.emailLogin(email, password);
this.error = this.authService.error;
}
}
}
If you use the above service you can login use. but it shows errors in the console if email and password are not correct, and it is not showing on binding with HTML.
The binding look like that.
<div class="alert alert-danger" role="alert" *ngIf="error">{{ error }}</div>
Now What I want, to send display error on first click as well as to get all the user data logged in.
I fond the solution. This service work for me.
import {AngularFireAuth} from 'angularfire2/auth';
#Injectable()
export class AuthService {
authState: any = null;
constructor(private afAuth: AngularFireAuth, private router: Router) {
this.afAuth.authState.subscribe((auth) => {
this.authState = auth
});
}
get isUserAnonymousLoggedIn(): boolean {
return (this.authState !== null) ? this.authState.isAnonymous : false
}
get currentUserId(): string {
return (this.authState !== null) ? this.authState.uid : ''
}
get currentUserName(): string {
return this.authState['email']
}
get currentUser(): any {
return (this.authState !== null) ? this.authState : null;
}
get isUserEmailLoggedIn(): boolean {
if ((this.authState !== null) && (!this.isUserAnonymousLoggedIn)) {
return true
} else {
return false
}
}
signUpWithEmail(email: string, password: string) {
return this.afAuth.auth.createUserWithEmailAndPassword(email, password)
.then((user) => {
this.authState = user
})
.catch(error => {
console.log(error)
throw error
});
}
loginWithEmail(email: string, password: string) {
return this.afAuth.auth.signInWithEmailAndPassword(email, password)
.then((user) => {
this.authState = user
})
.catch(error => {
console.log(error)
throw error
});
}
signOut(): void {
this.afAuth.auth.signOut();
this.router.navigate(['/'])
}
}
For more detail visit Angular 4 Firebase Auth – Email/Password Authentication with AngularFire2 v4

TypeError: Cannot read property 'Id' of undefined on edit view template - Angular 2

Okay so I have been facing the dreadful:
TypeError: Cannot read property 'Id' of undefined
Before we get started:
#angular/cli: 1.4.4
node: 6.10.3
npm: 3.10.10
Just to give more context, I am trying to perform one way data binding to edit a component by taking the Id from its component class and flow in a single direction to display the view template. That's all.
Below is the following that will hopefully try reproduce the problem and in turn figure out a solution.
SQL Table Definition:
CREATE TABLE [ExampleTable]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Col2] [nvarchar](50) NULL,
[Col3] [int] NULL,
[Col4] [int] NULL
)
ExampleTable.ts
export interface ExampleTable {
Id;
Col2;
Col3;
Col4;
}
export class CreateExampleTableModel {
SomeForeignKey?: number;
Col2: string;
Col2: number;
Col2: number;
}
export class EditExampleTable {
}
empty-tables.component.ts
import {
Component
} from '#angular/core';
import {
Router
} from "#angular/router";
import {
EmptyTableServiceService
} from "../../services/empty-table.service";
import {
EmptyTable
} from "../../models/outModels/EmptyTable";
#Component({
selector: 'app-empty-tables',
templateUrl: './empty-tables.component.html',
styleUrls: ['./empty-tables.component.css']
})
export class EmptyTablesComponent {
//Table data
emptyTable: EmptyTable[];
constructor(
private router: Router,
private emptyTableServiceService: EmptyTableServiceService) {
}
edit(emptyTable: EmptyTable) {
this.router.navigate(['emptyTables/edit', emptyTable.Id]);
}
}
EmptyTableService:
import {
Injectable
} from '#angular/core';
import {
Http
} from '#angular/http';
import 'rxjs/add/operator/toPromise';
import {
EmptyTable,
CreateExampleTableModel
} from "../models/outModels/EmptyTable";
#Injectable()
export class EmptyTableService {
constructor(private http: Http, ) {}
getEmptyTable(Id: string): Promise<EmptyTable> {
return this.http.get(`${this.auth.apiUrl}/api/emptyTables/get/${Id}`, { headers: this.auth.header })
.toPromise()
.then(response => response.json() as EmptyTable)
.catch(error => this.logging.handleError(error));
}
update(emptyTable: EmptyTable): Promise < EmptyTable > {
return this.http.post(`${this.auth.apiUrl}/api/emptyTables/update`, JSON.stringify(emptyTable), {
headers: this.auth.header
})
.toPromise()
.then(response => response.json() as EmptyTable)
.catch(error => this.logging.handleError(error));
}
}
EmptyTableEditComponent:
import {
Component,
OnInit
} from '#angular/core';
import {
ActivatedRoute,
ParamMap,
Router
} from '#angular/router';
import {
EmptyTableService
} from "../../../services/empty-table.service";
import {
EmptyTable
} from "../../../models/outModels/EmptyTable";
export class EmptyTableEditComponent implements OnInit {
model: EmptyTable;
constructor(
private route: ActivatedRoute,
private router: Router,
private emptyTableService: EmptyTableService
) {}
ngOnInit() {
this.loading = true;
this.route.paramMap
.switchMap((params: ParamMap) => this.emptyTableService.getEmptyTable(params.get('Id')))
.subscribe(emptyTable => {
this.model = emptyTable;
});
}
goBack(): void {
this.router.navigate(['/emptyTables']);
}
save(): void {
this.loading = true;
this.emptyTableService.update(this.model).then(
emptyTable => {
this.model = emptyTable;
},
error => {
console.log(error);
}
);
}
}
My suspicion is that in my getEmptyTable(Id: string) which returns a Promise of EmptyTables is that I am passing in my Id parameter as a string value whereas in my table definition from my DB it is an integer however according to my understanding, url parameters are always in string format. I tried the following:
i. Setting my Id to a number data type and I call the toString() on the Idparameter in the apiUrl like so:
getEmptyTable(Id: number): Promise<EmptyTable> {
return this.http.get(`${this.auth.apiUrl}/api/emptyTables/get/${Id.toString()}`, { headers: this.auth.header })
.toPromise()
.then(response => response.json() as EmptyTable)
.catch(error => this.logging.handleError(error));
}
But this does not make much of a difference. Lastly, please find the view template which I render:
<div class="container">
<p-messages [(value)]="messages"></p-messages>
<p-panel *ngIf="model">
<p-header>
Edit EmptyTable {{model.Name}}
</p-header>
<form name="form" (ngSubmit)="save()">
<div class="form-group">
<label>Col 2</label>
<input type="text" class="form-control" name="col2" [(ngModel)]="model.Col2" required />
</div>
<div class="form-group">
<label>Col 3</label>
<input type="text" class="form-control" name="col3" [(ngModel)]="model.Col3" required />
</div>
<div class="form-group">
<button pButton type="button" class="ui-button-secondary" (click)="goBack()" label="Back" icon="fa-chevron-left"></button>
<button pButton class="ui-button-success pull-right" label="Save" icon="fa-save"></button>
<app-loader *ngIf="loading"></app-loader>
</div>
</form>
</p-panel>
</div>
To wrap this up, it complains in the following function:
edit(emptyTable: EmptyTable) {
this.router.navigate(['emptyTables/edit', emptyTable.Id]);
}
Note: Please don't run the snippets as there is no output to them. This was the quickest way to format my code. Manual indentation was not cutting it.
The problem was found below:
<ng-template let-user="rowData" pTemplate="body">
<button type="button" pButton (click)="edit(distributor)" icon="fa-edit"></button>
</ng-template>
let-user should have been changed to let-distributor and all works.

Categories