Reputation: 728
First of all I have to say that I'm learning Angular. Maybe the answer is too evident but I can't see it. I've searched responses for similar questions in the web but I didn't found any that works for me.
I made an Angular Template Driven Form to store products on my Firebase Cloud Firestore Database. I created a model called "Product"
product.ts
export class Product {
constructor(
public code: string,
public desc: string,
public stock: number,
public price: number,
public off: number,
public details?: string
) {}
}
Then, I have the product.component.ts
import { Component } from '@angular/core';
import { Product } from './product';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-admin-product',
templateUrl: 'product.component.html'
})
export class AdminProductComponent {
model = new Product('', '', 0, 0, 0);
successMsg = 'Data successfully saved.';
productsRef: AngularFirestoreCollection<Product>;
product: Observable<Product[]>;
constructor(private afs: AngularFirestore) {
this.productsRef = this.afs.collection<Product>('productos');
}
save() {
this.productsRef.add(this.model).then( _ => alert(this.successMsg));
}
TypeScript doesn't return errors at all and everything seems to be ok. But when I run my app and try to save the form's data, console returns next error:
AdminProductComponent.html:51 ERROR Error: Function CollectionReference.add() requires its first argument to be of type object, but it was: a custom Product object
I solved it passing the custom object to a simple object like this:
const product = {
code: this.model.code,
desc: this.model.desc,
stock: this.model.stock,
price: this.model.price,
off: this.model.off,
details: this.model.details
}
And saving data like this:
save() {
this.productsRef.add(product).then( _ => alert(this.successMsg)); }
But I think that it isn't the properly solution, maybe could cause future issues scalling the app.
Upvotes: 8
Views: 13121
Reputation: 11
The below code worked for me in your Product.component.ts file
export class AdminProductComponent {
model:Product;
successMsg = 'Data successfully saved.';
productsRef: AngularFirestoreCollection<Product>;
product: Observable<Product[]>;
constructor(private afs: AngularFirestore) {
this.productsRef = this.afs.collection<Product>('productos');
}
save() {
const productData ={};
productData['code']:'123',
productData['desc']:'yes',
productData['stock']:500,
productData['price']:10000,
productData['off']:10
this.productsRef.add(productData).then( _ => alert(this.successMsg));
}
Upvotes: 1
Reputation: 1
You can also create a deep copy method within the Product
class, but this is less elegant.
export class Product {
constructor(
public code: string,
public desc: string,
public stock: number,
public price: number,
public off: number,
public details?: string
) {}
public getData(): object {
const result = {};
Object.keys(this).map((key) => (result[key] = this[key]));
return result;
}
}
And then use it as:
this.productsRef.add(product.getData()).then( _ => alert(this.successMsg)); }
Upvotes: 0
Reputation: 59
I used
save() {
const param = JSON.parse(JSON.stringify(this.model));
this.productsRef.add(param).then( _ => alert(this.successMsg));
}
Upvotes: 5
Reputation: 573
I used typescript spread operator
add(wizard: Wizard): Promise<DocumentReference> {
return this.wizardCollection.add({...wizard});
}
Upvotes: 24
Reputation: 6900
You can try this way, hope you are using latest typescript
product.ts
export interface Product {
code: string;
desc: string;
stock: number;
price: number;
off: number;
details?: string
}
in your product.component.ts
export class AdminProductComponent {
model:Product;
successMsg = 'Data successfully saved.';
productsRef: AngularFirestoreCollection<Product>;
product: Observable<Product[]>;
constructor(private afs: AngularFirestore) {
this.productsRef = this.afs.collection<Product>('productos');
this.model = {
code:'',
desc:'',
stock:0,
price:0,
off:0
}
}
save() {
this.productsRef.add(this.model).then( _ => alert(this.successMsg));
}
I think by doing this model = new Product('', '', 0, 0, 0);
you get an instance of the class not the object.
Upvotes: 8