I'm following a Typescript/Angular course that is showing me how to use "*ngIf". The instructor is giving an example of an empty array so that it fails the condition and compiles the second set of ul tags. It worked for the instructor, but not for me.
image-box.component.html
<div id="image-box">
<div class="left">
<img src="https://images.unsplash.com/photo-1606857521015-7f9fcf423740?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"/>
<app-title></app-title>
</div>
<div class="right">
<h3>Contracts</h3>
<ul *ngIf="contractInComponent.length > 0">
<li *ngFor="let contract of contractInComponent">
Service: {{ contract.service }} <br>
Title: {{ contract.title }}
</li>
</ul>
<ul *ngIf="contractInComponent.length == 0">
<li>Empty</li>
</ul>
</div>
</div>
get-data.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class GetDataService {
constructor() { }
getContracts() {
return [];
}
}
image-box.component.ts
import { Component, OnInit } from '#angular/core';
//import { ImageBoxService } from './image-box.service';
import { GetDataService } from './get-data.service';
#Component({
selector: 'app-image-box',
templateUrl: './image-box.component.html',
styleUrls: ['./image-box.component.scss']
})
export class ImageBoxComponent implements OnInit {
contractInComponent;
constructor(service:
GetDataService) {
this.contractInComponent = service.getContracts();
}
ngOnInit() {}
}
Compiled with problems:
ERROR
src/app/image-box/image-box.component.html:12:38 - error TS2339: Property 'service' does not exist on type 'never'.
12 Service: {{ contract.service }} <br>
~~~~~~~
src/app/image-box/image-box.component.ts:7:16
7 templateUrl: './image-box.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component ImageBoxComponent.
ERROR
src/app/image-box/image-box.component.html:13:36 - error TS2339: Property 'title' does not exist on type 'never'.
13 Title: {{ contract.title }}
~~~~~
src/app/image-box/image-box.component.ts:7:16
7 templateUrl: './image-box.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component ImageBoxComponent.
This works when I explicitly use Booleans. The first ul tag gets ignored and compiles the second set. The output is 0.
image-box.component.html
<div id="image-box">
<div class="left">
<!-- <h2>{{ contractInComponent[0].service }}</h2> -->
<img src="https://images.unsplash.com/photo-1606857521015-7f9fcf423740?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"/>
<app-title></app-title>
</div>
<div class="right">
<h3>Contracts</h3>
<ul *ngIf="false">
<li *ngFor="let contract of contractInComponent">
Service: {{ contract.service }} <br>
Title: {{ contract.title }}
</li>
</ul>
<ul *ngIf="true">
<li>{{ contractInComponent.length }}</li> <!-- output = 0 -->
</ul>
</div>
</div>
get-data.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class GetDataService {
constructor() { }
getContracts() {
return [];
}
}
Your compiler automatically determines a return type and sees that your getContracts() is always returning undefined. That's why you have the error. If you explicitly add a return type like this.
getContracts() : any {
return [];
}
The error will disappear because you tell the compiler it will potentially return something.
I only get an error due to the fact that you are injecting the dependency GetDataService as service but you are not creating the reference to it (aka missing the private word before the service word)
constructor(service:GetDataService){} //causes error
constructor(private service:GetDataService){} //works fine
You can see it running in this StackBlitz replication:
https://stackblitz.com/edit/angular-tdcxk7?file=src/test/test.component.ts
I'm developing an app using Laravel as backend and Angular as frontend. To login and register I'm trying to use JWT but when I try to register using the register form I get the following error: "ERROR TypeError: Cannot read property 'name' of undefined".
register.component.html
<form #registerForm=ngForm (ngSubmit)="onSubmit()">
<div class="form-group row mx-auto">
<label for="inputName3" class="col-md-6 col-form-label">Name</label>
<div class="col-md-12">
<input type="text" name="name" class="form-control"
placeholder="Name" [(ngModel)]="form.name" required>
<div class="alert alert-danger mt-2" [hidden]="!error.name">
<i class="fa fa-times-circle"></i> {{error.name}}
</div>
</div>
</div>
...
</form>
register.component.js
export class RegisterComponent implements OnInit {
public form = {
name: null,
email: null,
password: null,
password_confirmation: null
};
constructor(private http: HttpClient) { }
onSubmit(){
return this.http.post('http://localhost/api/auth/register',
this.form).subscribe(
data => console.log(data),
error => this.handleError(error)
);
}
ngOnInit() {
}
}
In the template, your test [hidden]='!error.name' is not valid because the variable error is not defined in the controller (.ts).
You should define error property with type object in the component.
because Angular expects an object called error with name key.
If you wait error from the backend or you need a quick solution just put ? (question mark) after error word in HTML like: [hidden]='!error?.name'.
This will make Angular check for error variable before checking for name property.
I am attempting to set up a ngb-datepicker to close on clicking outside of it. I am however receiving this error:
GamesComponent.html:9 ERROR TypeError: dp.close is not a function
at GamesComponent.push../src/web/apps/command-center/games/games.component.ts.GamesComponent.closeCalendar (games.component.ts:202)
at Object.eval [as handleEvent] (GamesComponent.html:12)
at handleEvent (core.js:10050)
at callWithDebugContext (core.js:11143)
at Object.debugHandleEvent [as handleEvent] (core.js:10846)
at dispatchEvent (core.js:7509)
at core.js:7953
at HTMLDocument.<anonymous> (platform-browser.js:1140)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:3748)
The relevant html is below
<ng-template #popContent class="col-lg-3 align-items-center">
<ngb-datepicker (select)="convertNgbDatetoDate($event)"
name="dp" ngbDatepicker #d="ngbDatepicker"
(blur)="onInputBlur()"
(document:click)="closeCalendar($event, d)">
</ngb-datepicker>
</ng-template>
and the ts
closeCalendar(event, dp) {
console.log(dp)
const path = event.path.map(p => p.localName);
if ((!path.includes('ngb-datepicker') && !path.includes('ng-
container') && !path.includes('gns-sentient-dates') &&
!path.includes('howser-input'))) {
dp.close();
this.onInputBlur();
}
}
Any ideas as to what I am missing?
Closing ngb-datepicker with clicking outside is an open issue of ng-bootstrap since 2016. Have a look at this issue.
Possible workarounds:
A)
use view:
(click)="d.toggle(); $event.stopPropagation();" (document:click)="d.close()"
or B)
use component:
if(!this._eref.nativeElement.querySelector('ngb-datepicker').contains(event.target)
&& !this._eref.nativeElement.querySelector('.input-group-addon').contains(event.target)) {
let self = this;
setTimeout(function(){
self.dynamicId.close();
},10);
}
or C)
use view:
<input style="background-color: white;" class="form-control" placeholder="YYYY-MM-DD" name="date" [(ngModel)]="date" ngbDatepicker #eToggle="ngbDatepicker" (click)="eToggle.toggle(); sToggle.close();$event.stopPropagation()" (document:click)="decideClosure($event, eToggle)" readonly>
and component:
decideClosure(event, datepicker) { const path = event.path.map(p => p.localName); if (!path.includes('ngb-datepicker')) { datepicker.close(); } }
So, before You read the whole error stack, keep in mind that at this time I cant pinpoint the exact piece that causes the problem. However, I will disclose the code below the error stack. So, my only question is: what parameters can't be resolved?
If you like, you can test my application for yourself. It is a simple default angular 6 application with all the default settings you get from the following command below:
ng new app-name
let's begin with the error. The application starts like normal. When I try to run the code, this error pops up: Uncaught Error: Can't resolve all parameters for Component: ([object Object]?). You can read the full error stack below.
Uncaught Error: Can't resolve all parameters for Component: ([object Object]?).
at syntaxError (compiler.js:1016)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (compiler.js:10917)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getTypeMetadata (compiler.js:10810)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:10429)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.loadDirectiveMetadata (compiler.js:10291)
at compiler.js:23865
at Array.forEach (<anonymous>)
at compiler.js:23864
at Array.forEach (<anonymous>)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._loadModules (compiler.js:23861)
syntaxError # compiler.js:1016
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata # compiler.js:10917
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getTypeMetadata # compiler.js:10810
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata # compiler.js:10429
push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.loadDirectiveMetadata # compiler.js:10291
(anonymous) # compiler.js:23865
(anonymous) # compiler.js:23864
push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._loadModules # compiler.js:23861
push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents # compiler.js:23839
push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync # compiler.js:23799
push../node_modules/#angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync # platform-browser-dynamic.js:143
push../node_modules/#angular/core/fesm5/core.js.PlatformRef.bootstrapModule # core.js:4352
./src/main.ts # main.ts:11
__webpack_require__ # bootstrap:76
0 # main.ts:12
__webpack_require__ # bootstrap:76
checkDeferredModules # bootstrap:43
webpackJsonpCallback # bootstrap:30
(anonymous) # main.js:1
As you see, there is no easy way of telling which part of my typescript is causing the problem. However, The application runs fine without the code in component.ts shown below. So, there is definitely something wrong with my typescript component.ts
the component.ts is shown below:
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, Directive} from '#angular/core';
import { FormGroup } from '#angular/forms';
import { DefineBusinessRuleService } from '../services/define/define-business-rule.service';
import { DefineBusinessRuleNamespace } from '../model/business-rule-namespace';
#Component({
selector: 'app-define-business-rule',
templateUrl: './define-business-rule.component.html',
styleUrls: ['./define-business-rule.component.css']
})
export class DefineBusinessRuleComponent implements OnInit {
// interfaces
headers : Headers;
output: any;
#Input() minValue: string;
#Input() maxValue: string;
#Input() attribute : Array<string>;
#Input() table : Array<string>;
submitted = false;
#Input() businessRuleType : Array<string>;
ruletypes : Array<string>;
ruletype : string;
constructor(
private defineBusinessRuleService: DefineBusinessRuleService
,private model : any
) {
this.table = ['table1', 'table2', 'table3'];
this.attribute = ['attribute1', 'attribute2', 'attribute3'];
this.ruletypes = [
// atrribute
'AttributeRange',
'AttributeCompare',
'AttributeList',
'AttributeOther',
'TupleCompare',
'TupleOther'
]
model = {
minValue : 5,
maxValue : 10,
name : 'RangeRule',
description : 'This is a Range Rule',
table1 : this.table[0],
column1 : this.attribute[2],
errorMsg : 'Error message'
};
}
get diagnostic() { return JSON.stringify(this.model); }
defineNewBusinessRule() {
//this.model = new DefineBusinessRuleService(42, 50, '', '', '', '', '');
}
saveAttributeRangeRule(){
this.output = {
database_id : 1,
minValue : this.minValue,
maxValue : this.maxValue,
table1 : this.table,
column1 : this.attribute
}
this.output.stringify;
this.defineBusinessRuleService.saveAttributeRangeRule(this.output);
}
saveAttributeCompareRule(){
this.output = {
database_id : 1,
table1 : this.table,
//table2 : this.table2,
column1 : this.attribute,
//column2 : this.attribute2,
//value : this.value
}
this.output.stringify;
//this.defineBusinessRuleService.saveAttributeCompareRule(this.output);
}
ngOnInit(){
}
onSelect(){
}
onSubmit() {
this.submitted = true;
this.ruletype = this.ruletypes[0];
switch(this.ruletype){
case "AttributeRange" : {
this.saveAttributeRangeRule();
break;
};
case "AttributeCompare" : {
this.saveAttributeCompareRule();
break;
};
}
}
}
Thanks for reading this! If you are visually orientated like me, then this form might help you understand what this code should do. However, it's off topic, since i'm certain enough that it doesn't cause operational problems in angular. keep that in mind!
the related html form is shown below
<br>
<br>
<main role="main" class="container">
<div class="container">
<h1>Define Business Rule</h1>
<form (ngSubmit)="onSubmit()" #defineBusinessRuleForm="ngForm">
<div class="form-group">
<label for="minValue">Minimum Value</label>
<input type="text" class="form-control" id="minValue">
</div>
<div class="form-group">
<label for="maxValue">Maximum Value</label>
<input type="text" class="form-control" id="maxValue">
</div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"
#name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
Name is required
</div>
</div>
<div class="form-group">
<label for="description">Description</label>
<input type="text" class="form-control" id="description" required>
</div>
<div class="form-group">
<label for="table">Table</label>
<select class="form-control" id="table" required>
<option *ngFor="let tbl of table" [value]="table">{{tbl}}</option>
</select>
</div>
<div class="form-group">
<label for="attribute">Attribute</label>
<select class="form-control" id="attribute" required>
<option *ngFor="let attr of attribute" [value]="attribute">{{attr}}</option>
</select>
</div>
<div class="form-group">
<label for="errorMsg">Error Message</label>
<input type="text" class="form-control" id="errorMsg" required>
</div>
<button type="submit" class="btn btn-success" [disabled]="!defineBusinessRuleForm.form.valid">Submit</button>
<button type="button" class="btn btn-default" (click)="defineNewBusinessRule(); defineBusinessRuleForm.reset()">Define New BR</button>
</form>
</div>
</main>
The error is in the model definition location.
private model: any should be defined as a parameter outside of a constructor.
By placing it in the constructor, the compiler is trying to resolve any class, and, naturally is unable to do so.
Modify your code this way:
export class DefineBusinessRuleComponent implements OnInit {
private model : any
constructor() {
this.model = {
// your model definition
};
}
// rest of the code
}
Hi there I want to know why it is throwing a warning on the console
Warning: Unknown prop `iconCLassNameRight` on <div> tag. Remove this prop from the element. For details, see link fb me
in div (created by Paper)
in Paper (created by AppBar)
in AppBar (created by App)
in div (created by App)
in MuiThemeProvider (created by App)
in App
The is the code I am working on it is on meteorjs and material ui
import React, { Component } from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import RaisedButton from 'material-ui/RaisedButton';
import AppBar from 'material-ui/AppBar';
import Player from './Player.jsx';
import TeamList from './Team-list.jsx';
import TeamStats from './Team-stats.jsx';
export default class App extends Component {
render(){
return (
<MuiThemeProvider>
<div className="container">
<AppBar
title="Soccer Application" iconCLassNameRight="muidocs-icon-navigation-expand-more" showMenuIconButton={false} />
<div className="row">
<div className="col s12 m7"> <Player /> </div>
<div className="col s12 m5"> <TeamStats /> </div>
<div className="col s12 m5"> <TeamList /> </div>
</div>
</div>
</MuiThemeProvider>
)
}
}
I want to know why this is throwing an error. The line of interest is in the appbar component iconClassNameRight property. Any help would be greatly appreaciated. Thank you.
Props in React are case-sensitive.
Try replacing iconCLassNameRight (uppercase L) to iconClassNameRight (lowercase L)