I'm building an application using angular that keeps track of composers and lists them. However, I keep getting these same two errors every time I try to build and run it. The errors are being found in my composer-details.component.ts file.
I'm fairly new to Angular so any advice would help a ton thank you!
composer-details.component.ts:23:3 - error TS2564: Property 'composer' has no initializer and is not definitely assigned in the constructor.
composer-details.component.ts:26:32 - error TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'.
composer-details.component.ts
import { Component, OnInit } from '#angular/core';
import { IComposer } from '../composer.interface';
import { ComposerService } from '../composer.service'
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-composer-details',
templateUrl: './composer-details.component.html',
styleUrls: ['./composer-details.component.css']
})
export class ComposerDetailsComponent implements OnInit {
composerId: number;
composer: IComposer;
constructor(private route: ActivatedRoute, private composerService: ComposerService) {
this.composerId = parseInt(this.route.snapshot.paramMap.get('composerId'), 10);
if (this.composerId) {
this.composer = this.composerService.getComposer(this.composerId);
}
}
ngOnInit(): void {
}
}
Try to use ! operator when initializing properties:
composerId!: number;
composer!: IComposer;
Related
I have this error:
Type {...} is missing the following properties from type 'any[]': length,pop,push,concat, and 28 more
I'm assigning album variable to the albumData array. Here is the code:
import { Component, OnInit } from '#angular/core';
import albumData from '../data/SearchResultsAlbum.json';
#Component({
selector: 'app-album-component',
templateUrl: './album-component.component.html',
styleUrls: ['./album-component.component.css']
})
export class AlbumComponentComponent implements OnInit {
album:Array<any>=[];
constructor() { }
ngOnInit(): void {
this.album=albumData;
}
}
What am I doing wrong? Thank you in advanvce!
album:any=[];
use this code instead of the code you have added
By default, Angular doesn't read the JSON file in the application. So we need to do some extra stuff for that. So we will create a file named 'json-typings.d.ts' inside the app folder of the project.
declare module "*.json" {
const value: any;
export default value;
}
source: https://jsonworld.com/demo/how-to-read-local-json-file-in-angular
I'm working with very basic angular project. I want to pass props between two angular components. The properties of a component are working fine when directly rendering them in the relevant HTML file. When passing it to another component it shows error.
HTML file of the parent component
<app-todo-item *ngFor="let todo of todos" [todo]="todo">
</app-todo-item>
The child component:
import { Component, OnInit,Input } from '#angular/core';
import { Todo } from 'src/app/models/Todo';
#Component({
selector: 'app-todo-item',
templateUrl: './todo-item.component.html',
styleUrls: ['./todo-item.component.css']
})
export class TodoItemComponent implements OnInit {
#Input() todo:Todo;
constructor() {
}
ngOnInit(): void {
}
}
The error I got:
Error: src/app/components/todo-item/todo-item.component.ts:11:12 - error TS2564: Property 'todo' has no initializer and is not definitely assigned in the constructor.
That comes from the new Ts compiler. Can fix with:
#Input() todo?: Todo;
What tells compiler this property is optional. Or:
#Input() todo!: Todo;
What tells compiler this property will not be unassigned
I'm new to Angular and creating a project that that uses routing. I'd like to import a js file from src/assets/js/custom.js
I've created a service that imports an injectable like so
test.service.ts
import { Injectable } from '#angular/core';
#Injectable()
export class TestService {
testFunction() {
console.log('Test');
}
}
home.compontents.ts looks like
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { TestService } from './test.service';
declare var require: any
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
providers: [TestService]
})
export class HomeComponent implements OnInit {
constructor() {private testService: TestService}
ngOnInit(): void {
this.testService.testFunction();
}
}
But I am getting the following error
17 constructor() {private testService: TestService}
~~~~~~~
src/app/home/home.component.ts:19:13 - error TS1005: ';' expected.
19 ngOnInit(): void {
~
src/app/home/home.component.ts:20:9 - error TS1005: ':' expected.
20 this.testService.testFunction();
~
src/app/home/home.component.ts:20:36 - error TS1005: ',' expected.
20 this.testService.testFunction();
~
src/app/home/home.component.ts:24:1 - error TS1128: Declaration or statement expected.
24 }
~
I've tried so many different ways from Google searches and not coming up with anything.
Can anyone please help?
UPDATE
Thanks for the updates, I've updated the constructor, however I am getting an error
ERROR in src/app/home/home.component.ts:3:29 - error TS2307: Cannot find module './test.service' or its corresponding type declarations.
3 import { TestService } from './test.service';
I'm not sure if I am going the right way with this. Each component I am using has 1 or 2 js files that I need to import. What would be the best way to do this?
A service passed as a parameter in class constructor to be injected as a dependency.
constructor(private testService: TestService) {}
The constructor is written incorrectly. Please write it as given below
constructor(private testService: TestService) {}
Also, you have given service as #Injectable(),then you have to define the service in app.module.ts file.
Alternatively, you can give
#Injectable({
providedIn: 'root'
})
This will eliminate adding the service in providers.
home.compontents.ts constructor should be like below:
constructor(private testService: TestService) {}
I am getting many errors at the dev tools console when adding a service into my component but the code still working but I want to get rid of from these errors
This's the service:
getPagesData(pageSlug: string): Observable<any[]> {
return this._http.get<any[]>(`${environment.apiUrl}wp/v2/pages/?slug=${pageSlug}`);
}
This is the component:
import { Component, OnInit } from '#angular/core';
import { DataService } from 'src/app/services/data.service';
#Component({
selector: 'app-membership',
templateUrl: './membership.page.html',
styleUrls: ['./membership.page.scss'],
})
export class MembershipPage implements OnInit {
public pageContent: any = {};
public content: string;
constructor(
private _data: DataService
) { }
ngOnInit() {
this._data.getPagesData('memberships')
.subscribe(
page => this.pageContent = page[0]
)
}
getContent(): string {
return this.pageContent.content.rendered.replace(/\[(.+?)\]/g, "");
}
}
What cause the errors is the getContent() method! it says that is the .rendered is an undefined property but it doses defined on the API!
I have searched on that problem and most of the solutions I found it's about using the symbol ? at HTML template but I can't use that in the component itself.
If you are calling getContent() in the HTML/template, you can most likely avoid this error by either:
Making pageContent initially null and using *ngIf to only display the content once it has asynchronously resolved:
Component:
public pageContent: any = null;
Template:
<div *ngIf="pageContent">{{getContent()}}</div>
Or you could instead RxJS operators such as map() and the async pipe:
Component:
import { Component, OnInit } from '#angular/core';
import { DataService } from 'src/app/services/data.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Component({
selector: 'app-membership',
templateUrl: './membership.page.html',
styleUrls: ['./membership.page.scss'],
})
export class MembershipPage implements OnInit {
public pageContent: Observable<string>;
public content: string;
constructor(private _data: DataService) { }
ngOnInit() {
this.pageContent = this._data.getPagesData('memberships')
.pipe(
map(page => page[0].content.rendered.replace(/\[(.+?)\]/g, ""))
);
}
}
Template:
<div>{{pageContent | async}}</div>
That being said, you should probably have additional checks to ensure each sub-property is available prior to accessing it, but usually this type of error is because you are attempting to access the contents before they have resolved.
Hopefully that helps!
Yes, you cannot use ? Elvis (Safe navigation) operator in the component itself because it is designed for view part only.
But you can add some check in the component too to avoid such errors like -
getContent(): string {
const dataToReturn = this.pageContent && this.pageContent.content && this.pageContent.content.rendered.replace(/\[(.+?)\]/g, "");
return dataToReturn
}
.rendered is an undefined property
Also, This error may produce you have defined pageContent = {} so on {} neither content nor rendered exist , may be that is also the reason to exist such errors.
Angular recommend to strongly typecast your data before use.
I am trying to show a material snackbar for the backend errors in my Angular 5 application.
I tried multiple ways but none worked, seems that the ErrorHandler class needs some special way to call the snackbar correctly.
Can someone please advise how to handle this?
I am getting this error:
Provider parse errors:
Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule#-1:-1
Evaluating main.ts
My custom ErrorHandler class is (without the imports) :
#Injectable()
export class MyErrorHandler implements ErrorHandler {
constructor(public snackBar: MatSnackBar) {}
handleError(error) {
const errorMsg = 'an error has happened';
this.openSnackBar(errorMsg);
}
openSnackBar(message: string) {
this.snackBar.open(message);
}
}
This is a stackblitz example to show what I mean
Note:
I have found this error in multiple questions but I can't exactly map the answers to my case
Angular loads ErrorHandler before the providers, this is the reason for your error about cyclic dependency.
So you need to inject the MatSnackBar manually, using the Injector, as this way:
import { Injectable, Injector } from '#angular/core';
import { MatSnackBar } from '#angular/material';
#Injectable()
export class MyErrorHandler implements ErrorHandler {
private snackbar;
constructor(private injector: Injector) {}
handleError(error) {
this.snackBar = this.injector.get(MatSnackBar);
const errorMsg = 'an error has happened';
this.openSnackBar(errorMsg);
}
openSnackBar(message: string) {
this.snackBar.open(message);
}
}
I have modified your stackblitz, now it works.