Errorcan't bind *ngFor - html

I'm a beginner in Angular and I'm trying to create an application that looks like CapitalistAdventure. But I have an error that I can't resolve and would like to receive some help please. First of all here is how looks my app:
The error is located at the app.component.html and it says:
Can't bind to 'product' since it isn't a known property of 'app-product'.
1. If 'app-product' is an Angular component and it has 'product' input, then verify that it is part of this module.
2. If 'app-product' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component.
Here is the code that I have for my app.component.html:
<h1><span id="WorldName">{{world.name}}WORLDNAME</span></h1>
<!--<span id="WorldImage"><img [attr.src]="server+world.logo"/></span>-->
<div class="UserData">
<div class="Money">
<span id="MoneyName">Money:</span>
<br>
<!--<span [innerHTML]="world.money | bigvalue"></span>-->
<span>$</span>
</div>
<div class="Buy">
<span id="BuyName">Buy</span>
</div>
<div class="ID">
<span id="MoneyName">ID :</span>
</div>
</div>
<div class="Game">
<div class="UpgradeContainer">
<div class="Upgrade" (click)="setModal('Unlock')">Unlocks</div>
<div class="Upgrade" (click)="setModal('Cash')">Cash</div>
<div class="Upgrade" (click)="setModal('Angels')">Angels</div>
<div class="Upgrade" (click)="setModal('Managers')">Managers</div>
<div class="Upgrade" (click)="setModal('Investors')">Investors</div>
</div>
<div class="ProductContainer">
<app-product *ngFor="let product of products" [product]="product"></app-product>
</div>
</div>
My app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { RestserviceService } from 'src/app/restservice.service';
import { HttpClientModule } from '#angular/common/http';
import { ProductComponent } from './product/product.component';
import { BigvaluePipe } from './bigvalue.pipe';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import {MatProgressBarModule} from '#angular/material/progress-bar';
#NgModule({
declarations: [
AppComponent,
ProductComponent,
BigvaluePipe,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
MatProgressBarModule,
],
providers: [RestserviceService],
bootstrap: [AppComponent]
})
export class AppModule { }
My app.component.ts:
import { Component } from '#angular/core';
import { RestserviceService } from './restservice.service';
import { World, Product, Pallier } from './world';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'AngularProject';
world: World = new World();
server: String;
products = [1,2,3,4,5,6];
modal: String;
constructor(private service: RestserviceService) {
this.server = service.getServer();
service.getWorld().then(world => { this.world = world; });
}
setModal(value: String){
this.modal = value;
}
}
My product.component.html:
<div class="Product">
<div class="ProductInfo">
<img onclick="alert('Production lancé'), starFabrication() " class="ProductImage" src="./assets/Avatar.jpg">
<!--<mat-progress-bar mode="determinate" class="ProgressBar" [value]="progressbarvalue"></mat-progress-bar>-->
<div class="ProductNumber">ProductNumber</div>
<div class="ProductPrice">ProductPrice</div>
</div>
</div>
And finally my product.component.ts:
import { Component, OnInit, Input } from '#angular/core';
import { Product } from 'src/app/world';
#Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
product: Product;
#Input()
set prod(value: Product){
this.product = value;
}
constructor() { }
ngOnInit(): void {
}
}
I'm precising but I'm on Angular 9.
Thanks in advance to anybody who would take the time to help me.

You need to move the #Input() decorator to bind to the product variable. Try the following
export class ProductComponent implements OnInit {
#Input()
product: Product;
constructor() { }
ngOnInit(): void {
}
}
OR
If you wish to use the #Input() decorator with the setter, then you need to bind to it's name in the template.
Controller
export class ProductComponent implements OnInit {
product: Product;
#Input()
set prod(value: Product){
this.product = value;
}
constructor() { }
ngOnInit(): void { }
}
Template
<app-product *ngFor="let product of products" [prod]="product"></app-product>

Related

Problem with My Wish List Items Showing Source unknown

I am having a problem showing my wish list items on the page. I'm using Angular 10 and json. Wen I click to add to favorites it color the heart and add it to to my json folder under wishlistitem, but when I route to page to look at the items no products are there. I can tell it hits the the *ngFor because the pipe for the dollar amount for each item appears but no images. When inspecting the source it shows src=unknown.
I have two folders wishlist-list and wishlistitem. I have a service for wishlistitem that is where I think my problem resides. I have included my code.
import { Component, OnInit, Input } from '#angular/core';
import {ProductService} from 'src/app/services/product.service'
import { MessengerService } from 'src/app/services/messenger.service';
import { WishlistService } from 'src/app/services/wishlist.service';
import { WishlistItemService } from '#app/services/wishlist-item.service';
import { Wish} from 'src/app/models/wish';
import {Product} from 'src/app/models/product';
#Component({
selector: 'app-wishlist-list',
templateUrl: './wishlist-list.component.html',
styleUrls: ['./wishlist-list.component.scss']
})
export class WishlistListComponent implements OnInit {
productList: Product[]= [];
wishlistItem: Wish[]= [];
wishItem = []
constructor( private msg: MessengerService,
private productService: ProductService,
private wishlistService: WishlistService,
private _wishlistitemService: WishlistItemService ) { }
ngOnInit(): void {
this.loadWishlistList();
}
loadWishlistList(){
this._wishlistitemService.getWishlistitem().subscribe((items: Wish[]) => {
this.wishItem= items;
this.msg.sendMsg("Is the item being captured" + items)
})
}
}
//Here is my Wishlist-list HTML
<p>wishlist-list works!</p>
<div class="container">
<div class="row">
<div class="col-md-2" *ngFor="let product of wishItem">
<app-wishlistitem [wishitemItem]="product"></app-wishlistitem>
</div>
</div>
</div>
//Here is my wishlist item service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { wishlistitemUrl } from 'src/app/config/api';
import { map } from 'rxjs/operators';
import { ProductItemComponent } from '#app/shopping-cart/product-list/product-
item/product-item.component';
import { Observable, of } from 'rxjs';
import { catchError} from 'rxjs/operators';
import {Product} from 'src/app/models/product';
import {Wish} from 'src/app/models/wish';
#Injectable({
providedIn: 'root'
})
export class WishlistItemService {
product:any
wishlistitemUrl = 'http://localhost:3000/wishlistitem';
constructor(private http: HttpClient) { }
getWishlistitem(): Observable<Wish[]>{
return this.http.get<Wish[]>(wishlistitemUrl)
.pipe(
map((result: any[]) => {
let wishItem: Wish[]= [];
for(let item of result) {
let productExists = false
if (!productExists){
wishItem.push(new Wish(item.id, item.name, item.description,
item.price, item.imageUrl);
}
}
return wishItem;
})
);
}
addProductToWishlistItem(product:Wish):Observable<any>{
return this.http.post(wishlistitemUrl, {product});
}
}
//Here is wishlistitem
import { Component, Input, OnInit } from '#angular/core';
import { ProductService } from 'src/app/services/product.service'
import { WishlistService } from 'src/app/services/wishlist.service';
import { WishlistItemService } from '#app/services/wishlist-item.service';
import { MessengerService } from 'src/app/services/messenger.service';
import { map } from 'rxjs/operators';
import { Wish } from '#app/models/wish';
import { Product } from '#app/models/product';
#Component({
selector: 'app-wishlistitem',
templateUrl: './wishlistitem.component.html',
styleUrls: ['./wishlistitem.component.scss']
})
export class WishlistitemComponent implements OnInit {
#Input() wishitemItem: Wish
#Input() productItem: Product
#Input() product: string
constructor(private wishlistService: WishlistService, private _wishlistitemService:
WishlistItemService, private msg:MessengerService ) { }
ngOnInit(): void {
}
//This function works as expected
handleAddToWishlistitem(){
this._wishlistitemService.addProductToWishlistItem (this.wishitemItem).subscribe(()
=>{
alert("Get wish list item");
this.msg.sendMsg(this.wishitemItem)
})
}
}
//Here is wishlistitem Html
<p>wishlistitem works!</p>
<div class="test">
<div class="container" style="margin:0 auto">
<div class="row no-gutters" style="margin-top: 30px">
<div class="col-4">
<img class="shacker" [src]="wishitemItem.imageUrl" />
<div class="card-body">
<p class="card-text" style="text-align:left; width:130px">
{{wishitemItem.name}}</p>
<p class="card-text" style="text-align:left; width:130px;">
<strong>{{ wishitemItem.price | currency }}</strong>
</p>
<p class="card-text" style="text-align:left; width: 150px">
{{wishitemItem.description | slice: 0:20}}...</p>
</div>
</div>
</div>
</div>
</div>
//I hope the explanation is sufficient. I have tried many scenarios, the issue I'm
having is with the property for the wishlist item, carItem does not have a property
and when I create one the application doesn't behave as expected.
Thank you in advance
PDH

Angular service not passing form data after routing

New to Angular and I feel like there's just an obvious mistake I am missing, code-wise.
I'm trying to follow the tutorial here: https://youtu.be/CUAHJxWGia0
I have one component to create/add an employee's ID called CreateEmployee.
On submission, it should route to a component to list all employees (ListEmployees).
It's using employee.service.ts.
When I click submit (before or without routing), it correctly logs the employee input to the console on CreateEmployee.
The problem is that when routing to the second component, ListEmployees, my new entry is not displayed at all, and only my test data is displayed.
I've made sure EmployeeService is included in my app.module as well.
create-employee.ts:
import { Component, OnInit } from '#angular/core'
import { FormControl, FormBuilder, NgForm } from '#angular/forms'
import { EmployeeService } from 'app/services/employee.service'
import { Router } from '#angular/router'
import { Employee } from 'app/shared/employee.model'
#Component({
selector: 'app-create-employee',
template: ` <form class="" [formGroup]="employeeForm" (ngSubmit)="saveEmployee()">
<div class="form-control">
<app-input
#memberID
name="memberID"
label="Member ID"
formControlName="memberID"
placeholder="Member ID"
></app-input>
</div>
<div><button type="submit" class="">Save</button></div>
</form>
{{ employeeForm.value | json }}
`,
styleUrls: ['./create-employee.component.scss'],
})
export class CreateEmployeeComponent implements OnInit {
employeeForm: any
constructor(private fb: FormBuilder, private _employeeService: EmployeeService, private _router: Router) {}
employee: Employee = {
memberID: null,
}
ngOnInit(): void {
this.employeeForm = this.fb.group({
memberID: new FormControl(''),
})
this.employee = this.employeeForm.get('memberID').value
}
saveEmployee() {
this._employeeService.save(this.employee)
console.log(this.employeeForm.get('memberID').value)
// this._router.navigate(['employee-list'])
}
}
list-employee.ts
import { Component, OnInit } from '#angular/core'
import { Employee } from 'app/shared/employee.model'
import { EmployeeService } from 'app/services/employee.service'
#Component({
selector: 'app-list-employees',
template: `<div *ngFor="let employee of employees">
<div class="">
{{ employee.memberID }}
</div>
</div> `,
styleUrls: ['./list-employees.component.scss'],
})
export class ListEmployeesComponent implements OnInit {
employees: Employee[] = []
constructor(private _employeeService: EmployeeService) {}
ngOnInit(): void {
this.employees = this._employeeService.getEmployees()
}
}
employee.service.ts
import { Injectable } from '#angular/core'
import { Employee } from 'app/shared/employee.model'
#Injectable({
providedIn: 'root',
})
export class EmployeeService {
listEmployees: Employee[] = [{ memberID: '1' }, { memberID: '2' }]
constructor() {}
getEmployees(): Employee[] {
return this.listEmployees
}
save(employee: Employee) {
this.listEmployees.push(employee)
}
}

angular 6 with jsonplaceholder , opening posts/${id} after clicking button

I am working on a dummy app with jsonplaceholder, I am getting all posts but i am unable to get post with dynamic id like posts/${id}. How can i achieve this. kindly help.
I am having basic generate angular app.
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<h1>{{title}}</h1>
<!-- -->
<main *ngIf="!some; else elseBlock">
<section *ngFor="let dt of data">
<aside>ID: <span id="id">{{dt.id}}</span></aside>
<aside>Title: {{dt.title}}</aside>
<button (click)="linkto()">click to view</button>
<br>
<hr>
</section>
</main>
<ng-template #elseBlock>
<section>
<aside>ID: {{data2.id}}</aside>
<aside>Title: {{data2.title}}</aside>
<aside>Body: {{data2.body}}</aside>
<button (click)="linkto()">back</button>
<br>
<hr>
</section>
</ng-template>
app.component.ts
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app';
constructor(private http : HttpClient){
this.showPost();
}
data :any = [];
id: any;
data2 :any = {};
some: boolean;
showPost() {
this.http.get('https://jsonplaceholder.typicode.com/posts')
// clone the data object, using its known Config shape
.subscribe(data => {
console.log('**************',data);
this.data = data
});
}
linkto(){
this.showPost2();
this.some = !this.some;
}
showPost2() {
this.http.get(`https://jsonplaceholder.typicode.com/posts/${id}`)
.subscribe(data2 => {
this.data2 = data2;
});
}
}
i am also interested if is there any shorter way to do this?
like simple on one page . i am making get requests but after this i will be making post, put , patch and delete too. on app.component.html page itself.
You should send id from html to component using linkto(dt.id)
Then you can use that id as a parameter in your component methods.
HTML:
<main *ngIf="!some; else elseBlock">
<section *ngFor="let dt of data">
<aside>ID: <span id="id">{{dt.id}}</span></aside>
<aside>Title: {{dt.title}}</aside>
<button (click)="linkto(dt.id)">click to view</button>
<br>
<hr>
</section>
</main>
<ng-template #elseBlock>
<section>
<aside>ID: {{data2.id}}</aside>
<aside>Title: {{data2.title}}</aside>
<aside>Body: {{data2.body}}</aside>
<button (click)="linkto(dt.id)">back</button>
<br>
<hr>
</section>
</ng-template>
Component:
linkto(id){
this.showPost2(id);
this.some = !this.some;
}
showPost2(id) {
this.http.get(`https://jsonplaceholder.typicode.com/posts/${id}`)
.subscribe(data2 => {
this.data2 = data2;
});
}

Route navigation in Angular4 not reacting

I have made an Angular4 component and the page that it generates has a button to navigate to another page. I don't get any errors and the pageUrl changes but the content of the page stays the same.
Here is my code:
app.component.ts
import { Component } from '#angular/core';
import { Router } from "#angular/router";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router){}
username = "";
password = "";
log = function () {
if (this.username != "" && this.password != "") {
console.log(this.username + " " + this.password);
this.router.navigate(['/dashboard']);
}
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component';
#NgModule({
declarations: [
AppComponent,
DashboardComponent,
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{
path: 'dashboard',
component: DashboardComponent
}
]
)
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {
}
app.component.html
<div class="outer-container">
<div class="inner-container">
<div class="centered-content">
<div class="center"><img src="../favicon.png"></div>
<label class="addText"> Username: </label><input [(ngModel)]
="username" class="addText"><br>
<label class="addText"> Password: </label><input [(ngModel)]
="password" type="password" class="addText"><br>
<div class="center"><button (click) ="log()">Log in</button></div>
</div>
</div>
</div>
To achieve what you want, have the app.component only to include the router-outlet:
#Component({
selector: 'app-root',
template: `
<!-- Views go here-->
<router-outlet></router-outlet>
`,
})
export class AppComponent { }
And then have a separate component for each view you want. So in your case you'd want to create a LoginComponent, which would then route to the DashboardComponent from there.
PS Of course this is expandable and you could add a header component tag in the AppComponent html, or whatever else and so on and so on. But just to showcase this simple use case.
you need to specify where to display the DashboardComponent
add this tag to tell angular the location where to display the component results from router
<router-outlet></router-outlet>

Show related product for perticular Pincode using service provider in angular2

I want to create a single page application without use of routing,that will show when i give input for pincode,it will show the product for that pincode using service and injection.i am a bit confuse to create it.
Here is my product.service.ts
import { Injectable } from '#angular/core';
import { Product } from './product';
#Injectable()
export class ProductService {
private products: Product[] = [
new Product('10', 'schezwan rice', 'with schezwan sauce tasty', 'http://www.foodinnrestaurant.com/images/stories/virtuemart/product/prodt_328.jpg'),
Product('11', 'Summer salad', 'looks tasty and healthy', 'http://images.media- allrecipes.com/userphotos/250x250/00/39/70/397065.jpg')
];
constructor() { }
getProducts() {
return this.products;
}
}
I make a class for product
In product.ts
export class Product {
constructor (public pin: number, public name: string, public description: string, public imagePath: string) {
}
}
Here is my product-group component
<div class="row">
<div class="col-xs-12">
<ul class="list-group">
<li *ngFor="let product of products" [product]="product"(click)="onSelected(product)"></li>
</ul>
</div>
</div>
here is my product-group.ts code
import { Component, OnInit, Input } from '#angular/core';
import { Product } from '../product';
#Component({
selector: 'ps-product-group',
templateUrl: './product-group.component.html',
styleUrls: ['./product-group.component.css']
})
export class ProductGroupComponent implements OnInit {
#Input() product: Product;
constructor() { }
ngOnInit() {
}
}
Here is my pincode.ts code
import { Component, OnInit, EventEmitter, Output } from '#angular/core';
import { Product } from '../product';
import { ProductService } from '../product.service';
#Component({
selector: 'ps-pincode',
templateUrl: './pincode.component.html',
styleUrls: ['./pincode.component.css'],
providers: [ProductService]
})
export class PincodeComponent implements OnInit {
products: Product[] =[];
#Output() productSelected = new EventEmitter<Product>();
ngOnInit() {
}
onSelected(product: Product) {
this.productSelected.emit(product);
}
}
here is my pincode html component
<div class="container">
<div class="form-group">
<input type="number" class="form-control" placeholder="Enter your pincode">
</div>
<button type="submit" class="btn btn-default" (click)="onSelected(products)" >Submit</button>
</div>