Identifier 'image' is not defined. 'never' does not contain such a member - html

Edit :: The output is added. I getting the output successfully, but I just don't know why I am getting this error. I had already done this before but now I am facing this error. I had tried using "?" and "!!" but still not fixing. What is this and how to fix this..
Edit ::
html
<div class="container" *ngFor="let data of data">
<a href="{{ data.url }}"> //error in url ( Identifier 'url' is not defined. 'never' does not contain such a member )
<img src="{{ data.image }}"> // error in image ( Identifier 'image' is not defined. 'never' does not contain such a member )
</a>
</div>
ts file
import { Component, OnInit } from '#angular/core';
import { ApiService } from 'src/app/services/api.service';
#Component({
selector: 'app-technology',
templateUrl: './technology.component.html',
styleUrls: ['./technology.component.css']
})
export class TechnologyComponent implements OnInit {
data = [];
constructor(private apiservice : ApiService) { }
ngOnInit() {
this.apiservice.getTechUrl().subscribe(async (data : any) => {
this.data = await data.articles
})
}
}
I found the solution for this
I had just changed the data = []; to data : any; and there is no error and i also got the output without any error.

Error template syntax ngFor="let data of data"
ngFor can't use check point name same array data name.
Try this
<div class="container" *ngFor="let item of data">
<a href="{{ item.url }}">
<img src="{{ item.image }}">
</a>
</div>
hope help you

I found the solution
I just changed the data = []; to data: any; in the .ts file and then there is not error;
but I still don't know what is the exact reason for that error.
I don't if I am right about this the Json file which I was receiving is of type object and storing inside the data of array given me the error but after changing the to data: any; I am not giving any specific type in here, it may be of any type so error is gone.

Related

Why ngfor directive is not working, though I have created proper object in Typescript class

I have created proper Ingredient object in Typesript, also proper "model" for the object. Though ngfor directive is not working. I am getting this error "NG0303: Can't bind to 'ngforOf' since it isn't a known property of 'a'" on inspecting in browser.
My model code
export class Ingredient {
constructor(public name: string, public amount: number){}
}
My TypeScript code
import { Component, OnInit } from '#angular/core';
import { Ingredient } from '../shared/ingredient.model';
#Component({
selector: 'app-shopping-list',
templateUrl: './shopping-list.component.html',
styleUrls: ['./shopping-list.component.css']
})
export class ShoppingListComponent implements OnInit {
ingredients: Ingredient[] = [
new Ingredient ("Apple", 5),
new Ingredient ("Tomato", 5)
];
constructor() { }
ngOnInit(): void {
}
}
My HTML code
<div class="row">
<div class="col-xs-10">
<app-shopping-edit></app-shopping-edit>
<hr>
<ul class = "list-group">
<a class = "list-group-item"
style = "cursor : pointer"
*ngfor = "let ingredient of ingredients">
{{ ingredient.name }}({{ ingredient.amount}})
</a>
</ul>
</div>
</div>
Page is loading properly, but ingredients are not loading. On inspecting in browser this error "NG0303: Can't bind to 'ngforOf' since it isn't a known property of 'a'" is coming.
Can someone please help.
Try moving the *ngFor inside the ul tag.
Edit: You have a typo.. It's *ngFor="", not *ngfor="".
If you are inside AppModule check if you have BroswerModule in the imports array there.
If you are in some different module then check if CommonModule is a part of that module's array. CommonModule provides us with core Angular features like *ngIf or *ngFor in your specific case.
Also watch out, you typed *ngfor instead *ngFor.

Angular product-details.component.html Object is possibly 'undefined'

I'm following the View Product Details tutorial on the angular website and encountered the error:
Error in src/app/product-details/product-details.component.html (4:16)
Object is possibly 'undefined'.
I can't proceed to the next tutorial because it needs this page to function.
Here is the code:
product-list.component.html
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
<a [title]="product.name + ' details'" [routerLink]="['/products', product.id]">
{{ product.name }}
</a>
</h3>
</div>
product-details.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { Product, products } from '../products';
#Component({
selector: 'app-product-details',
templateUrl: './product-details.component.html',
styleUrls: ['./product-details.component.css']
})
export class ProductDetailsComponent implements OnInit {
product: Product|undefined;
constructor(
private route: ActivatedRoute,
) { }
ngOnInit() {
// First get the product id from the current route.
const routeParams = this.route.snapshot.paramMap;
const productIdFromRoute = Number(routeParams.get('productId'));
// Find the product that correspond with the id provided in route.
this.product = products.find(product => product.id === productIdFromRoute);
}
}
product-details.component.html
<h2>Product Details</h2>
<div *ngIf="product">
<h3>{{ product.name }}</h3>
<h4>{{ product.price | currency }}</h4>
<p>{{ product.description }}</p>
</div>
I hope someone can help to figure out the problem because I see the code is functioning.
Thank you.
I'm also doing this tutorial and I fixed it by adding the ProductDetailsComponent to the declarations inside app.module.ts.
declarations: [
AppComponent,
TopBarComponent,
ProductListComponent,
ProductAlertsComponent,
ProductDetailsComponent //<-- add this into declarations
],
Don't forget to import first the ProductDetailsComponent in app.module.ts.
import { ProductDetailsComponent } from './product-details/product-details.component';
It should work after refreshing the entire website (not just the display to the right, go save and refresh the browser tab).
You might want to try using product?.name
I fixed that by adding 'ProductDetailsComponent' import in 'app.module.ts'
tsconfig.json file
"strict": false,
Turn off the strict. Angular will able to compile successfully.

Facing Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked

I am trying to assign a random color to the div background using the below example
Random Color
But facing below error:
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has
changed after it was checked.
You can check-in console of created stackblitz.
I have already tried the below answers:
How to manage Angular2 "expression has changed after it was checked" exception when a component property depends on current datetime
Expression ___ has changed after it was checked
But no luck! Can anyone please look into this and help?
One solution for this is to use a directive.
So I created a directive called appRandomColor
Here's the code for it.
import {Directive, ElementRef, Input, OnInit} from '#angular/core';
#Directive({
selector: '[appRandomColor]'
})
export class RandomColorDirective implements OnInit {
constructor(private element: ElementRef) { }
ngOnInit() {
this.element.nativeElement.style.color = this.getRandomColor();
}
getRandomColor() {
var color = Math.floor(0x1000000 * Math.random()).toString(16);
return '#' + ('000000' + color).slice(-6);
}
}
And added it to declarations in AppModule
Then I applied it to the *ngFor loop. And no errors.
<ul>
<li class="hero" *ngFor="let hero of heroes" appRandomColor>
{{ hero }}
</li>
</ul>
I suggest reading more about Angular Change Detection because it will help you understand these errors more.
Here are some articles that I find very helpful
https://indepth.dev/a-gentle-introduction-into-change-detection-in-angular/
https://indepth.dev/everything-you-need-to-know-about-change-detection-in-angular/
Edit
On Component.ts
colorsArray = ['#FF5733', '#DA4323', '#FFB1A0', '#BB523C', '#BB2505', '#DE4922'];
On Component.html
<li class="hero" *ngFor="let hero of heroes" [appRandomColor]="colorsArray">
{{ hero }}
</li>
To add predefined colors array to directive
#Input('appRandomColor') colors: string[];
ngOnInit() {
this.element.nativeElement.style.color = colors[Math.floor(Math.random() * colors.length)];
}

ngif stays false, even though its value is right

My code looks like this:
component.ts
export class ViewScaleComponent implements OnInit {
private range$: Observable<number>;
constructor(private store: Store<AppState>) {}
ngOnInit() {
this.range$ = this.store.select(x => x.view.range);
}
}
component.html:
<div *ngIf="(range$ | async)">
here {{ range$ | async }}
</div>
The div remains commented in the DOM, an Angular Ghost.
If I remove ngif, the div appears, but the data interpolation fetches nothing (only here and the following whitespace appears).
If in ngOnInit() I do:
this.range$ = this.store.select(x => x.view.range).do(x => console.log(x));
console.log("on init " + this.range$);
then I get:
on init [object Object]
undefined
21
where the last two console logs come from the same line (do()). I wonder whether the first undefined is the reason for not displaying the di.
It's worth noting that sometimes it works(I see the div and the values ofrange$ are being updated as expected).
Any ideas?
PS: I read angular 2 ngIf with observable?, but the observable and async combination look pretty similar to mine.
You dont need the ngIf for this just put {{ range$ | async}}
Update
range:any ;
ngOnInit() {
this.store.select(x => x.view.range).subscribe(x => this.range = x);
}
Template
<div *ngif="range">
here {{ range }}
</div>

caused by: Cannot read property 'product_name' of undefined

When I try to load a html form component in my angular2 app, it will not read a property on one part of the form.
EXCEPTION: Uncaught (in promise): Error: Error in
http://localhost:3000/app/material/material-new.component.html:15:7
caused by: Cannot read property 'product_name' of undefined
I have another component that is identical bar the fields and does not encounter this problem when loaded. Components match and I am going mad about this.
Why does it not read that property of 'product_name' .
Heres the code.
Create Material
<div class="card container form-container">
<div class="row">
<div class="col-md-12">
<form (ngSubmit)="createMaterial(material)" #materialForm="ngForm" >
<div class="form-group">
<label class="label-text" for="product_name">Product
Name</label>
<input type="text"
class="form-control"
id="product_name"
placeholder="Product name"
required
name="product_name"
#product_name='ngModel'
[(ngModel)]="material.product_name">
<div [hidden]="product_name.valid || product_name.pristine">
Input product name
</div>
</div>
import { Component } from '#angular/core';
import { Material } from './material';
import { MaterialService } from './material.service';
import { Observable } from 'rxjs/Rx';
#Component({
moduleId: module.id,
selector: 'material-new',
templateUrl: 'material-new.component.html',
styleUrls: ['material-new.component.css'],
providers: [ MaterialService ]
})
export class MaterialNewComponent {
material : Material;
submitted : boolean = false;
constructor(
private materialService : MaterialService
) {}
createMaterial( material : Material) {
this.submitted = true;
this.materialService.createMaterial(material)
.subscribe(
data => { return true },
error => { console.log("error saving material")
return Observable.throw(error);
}
)
}
}
You error points to [(ngModel)]="material.product_name"
Your material object is undefined, because you have not initialized it. So all you need to do, is to initialize your Object.
So change:
material : Material;
to
material : Material = <Material>{};
and it will no longer be undefined.
You should use async pipe to unwrap the Observable because it does the job of subscribing and unsubscribing automatically.
What you'll need to do:
TS Code:
material: Observable<Material>;
// In createMaterial
this.material = this.materialService.createMaterial(material);
Template:
[(ngModel)]="(material | async)?.product_name"
The ? will check if material | async is undefined.