Vscode-ng-language-service: Support optional chaining in template

Created on 18 Aug 2017  ·  70Comments  ·  Source: angular/vscode-ng-language-service

in 0.1.4 on Windows 10

errors?.required is highlighted as an error

Name is required

image

bug

Most helpful comment

this worked for me:

 picture Ahnset on 18 Jan 2018
👍38 😄10 👎98 🎉7 🚀2

All 70 comments

Also happening on OS X 10.11.6 (El Capitan).

OS: OS X 10.11.6
Extension version: 0.1.4
VS Code version: 1.15.1

I also got this problem on Window 10 x64
Extension version 0.1.7
VS Code version 1.15.1
Please fix it soon

Same problem here.
Error is: 'Identifier 'errors' is not defined. 'NgModel' does not contain such a member'.

OS: macOS 10.13
Extension: 0.1.7
VS Code: 1.16.1
Angular: 4.4.3
Typescript: 2.5.2

Same problem! Any solution?

Should I import it in the app.module or in my component where the form is exist?

The @angular/forms imports mentioned by @VladBozhinovski won't solve it.
Kind of related: https://github.com/angular/vscode-ng-language-service/issues/179

Yeah didn't work me either...

i have same problem .... any solution ?

Same Issue, has anyone found a fix?

Same issue here. Any ideas yet?

I also got this problem any solutions

Same here.

it seems like I'm not alone :)

So many people got this problem. You guys can prevent it like 'email?.error.required'

@Duanthse03268 this worked by removing the red line error but still get the following console error, any idea why ?

FoodFormComponent.html:9 ERROR TypeError: Cannot read property 'minlength' of undefined at Object.eval [as updateDirectives] (FoodFormComponent.html:10) at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13056) at checkAndUpdateView (core.es5.js:12236) at callViewAction (core.es5.js:12601) at execComponentViewsAction (core.es5.js:12533) at checkAndUpdateView (core.es5.js:12242) at callViewAction (core.es5.js:12601) at execComponentViewsAction (core.es5.js:12533) at checkAndUpdateView (core.es5.js:12242) at callWithDebugContext (core.es5.js:13456)

Make sure u import
import { FormsModule, Validators } from '@angular/forms';

None of the solutions in this thread resolve the issue. I made an example as simple as possible to make sure nothing else was messing it up:

screen shot 2018-01-08 at 22 56 53

FormModule and Validators have been imported from @angular/forms. I also tested this solution by @Duanthse03268, and not only does it not resolve the red line issue, it also causes an error in console when the state of myField changes (TypeError: Cannot read property 'required' of null) if used without the '?' after 'errors'.

My implementation works without errors in the browser but retains the (supposedly incorrect) red line in editor (VSCode). Gists of the files in question (everything else you can simply 'ng new...' to reproduce):

app.module.ts
app.component.ts
app.component.html

Versions:

Extension: 0.1.7
VSCode: 1.19.1
Angular CLI: 1.6.3
Node: 9.2.1
OS: macOS 10.12.6
Angular: 5.1.3
Chrome: 63.0.3239.84

Why did not you try to use 'myfield?.error.required' .

I did try it, just as I wrote in my previous comment: "not only does it not resolve the red line issue, it also causes an error in console when the state of myField changes (TypeError: Cannot read property 'required' of null)".

So, to elaborate, 'myField?.errors.required' does not work and causes the above error message to be displayed in console. The '?' has to be written after 'errors' in order to have this code work in browser without error message, yet does not solve the original issue of incorrect red line in editor.

This is extremely annoying as the red lines are there still but the functionality works. I agree with joonashak as the solutions presented do not work and trying both formats do not resolve the issue.

this worked for me:

Ahnset picture Ahnset on 18 Jan 2018
👍38 😄10 👎98 🎉7 🚀2

Only workarounds :(

IntelliJ throws the same error for me. But the implementation works even with the errors in the browser. Workaround by @Ahnset worked for me. Would like to know what is this syntax and how is it working now?

I found that this error appears every time you reference a property which is defined as 'any'. Another workaround is using the bracket property annotation, clientFirstName?.errors['required'] which is also pretty stupid.

Its getting worst, with the latest update of vscode, my file tree has become more like a christmas tree :christmas_tree:

@adickenscheidt thank you for the workaround. Works great, agree dumb for now.

removed Angular Language Service...

@Duanthse03268 Your function work! Thanks.

@adickenscheidt
Thanks this solution work for me

It worked. Much appreciated @Duanthse03268

@Duanthse03268 Your function work! But what does it mean exactly?

It doesn't work for nested object property
<mat-select [(ngModel)]="object?.nestedObject?.property" name="property" #property="ngModel">
getting supercool parsing errors on object?.object?.property

I use this. Ugly but works.
name?.errors && name?.errors['required']

email.errors['required'] worked for me

@guignol1981 Solution worked for me.

Using this worked for me:

renemaldonado picture renemaldonado on 22 May 2018

I have the same issue, but none of the proposed solutions have worked:
"form?.get('name').errors.required"
"form?.get('name').errors.['required']"
"form?.get('name').errors?.required"

Hello try it like this.
Form.hasError('required');

That worked for me. Thanks @antonheck

there are a few workarounds, each better for different situation, yes. But that is not the issue. I shouldn't have to write my code differently, including ugly, hacky sintaxe, only to appease an IDE extension, when what I wrote was right from the start.

I have exactly same problem and message with this similar code :

class MyComponent {
  form: FormGroup;
}

with lines like this in the template :

<app-errors [control]="form.controls.email">

Error message :

Identifier 'email' is not defined. '__type' does not contain such a member

Problem is caused by fields of type like (it occurs with AbstractControl or something else of course) :

{  [key: string]: AbstractControl;  };

I have this message in Visual Studio Code (Windows) and Angular Language Services, but not with ng lint.

Best solution so far:

Try prepend "!!".
Although it is tricky,
I succeeded this way.

image

_from: https://github.com/angular/vscode-ng-language-service/issues/126#issuecomment-366200219_

Thanks tmrony, best solution after many days searching...

Actually it's supposed to be like this, the error highlight is shown because the "errors" property of "AbstractControl" has no strictly defined properties, it's of type "ValidationErrors"

So directly accessing a validation rule is causing the error, in my case accessing it using square bracket notation solves the issue.

(btw even if i access the validation property directly i am not getting compilation errors, the app works fine either way)

image

The other way to do this is to use "hasError" method of the control:

   <span *ngIf="(firstName.dirty || firstName.touched) && firstName.hasError('required')">First name is required.</span>

@boban984 Solution worked....

@adickenscheidt Solution worked for me! thanks

"price.errors['required']" --> Worked
"!!price.errors.required" --> Worked

"price?.errors?.required" should also work, because my "fullname?.errors?.required" works

"price.errors['required']" --> Worked

That doesn't trigger the compiler 'identifier is not defined' but it's not a good solution, because if errors object is null, it will error on the console about it.

@boban984
this is the winner solution and explanation.

I was glad to find the hasError() method discussed here, it's certainly the clearest way to show the intent of the template conditional and I think I'll try to use it exclusively going forward.

However... nobody is addressing the root cause of the problem, and it's been an issue with the language service for something like a year now. The errors property has a key index signature ([key: string]: any) which means that in TS code, the statement myControl.errors.anythingYouLike will compile cleanly, no matter what strict-mode flags you have set. This is correct, because the entire point of having an index signature like that is to be able to create arbitrary properties at runtime, and access them by either dot-notation or index-notation. The language service allows index-notation, which is why control?.errors['required'] works, but flags dot-notation as incorrect, which is an error.

three solutions:

<span *ngIf=" username.errors['email']">must be email</span>

<span *ngIf="!!username?.errors.email">must be email</span>

<span *ngIf="username.hasError('email')">must be email</span>

I like the third best

@boban984 Great solution and explanation

thnks, works for me!. 👍🏼
i hate view Errors on console 😬

Hello try it like this.
Form.hasError('required');

This was the most elegant solution, and really works for all cases: myForm.hasError('required', 'myField').

Thanks @antonheck

Hello try it like this.
Form.hasError('required');

This was the most elegant solution, and really works for all cases: myForm.hasError('required', 'myField').

It works, but the best solution based on simplicity was offered by @boban984: "myField.hasError('required')". :)

I solved this problem in this way:

  • example.component.ts:
this.myForm = this.formBuilder.group({
      field: ['', [Validators.required, Validators.maxLength(10)]]
});

get getField() { return this.myForm.get('field'); }
  • example.component.html:
<div *ngIf="getField.errors" class="invalid-feedback">
  <div *ngIf="getField.hasError('required')"> Text required </div>
  <div *ngIf="getField.hasError('maxlength')"> Text maxLength </div>
</div>

I hope to be helpful.

Perfect @bePericon this works for me!
Thanks!

<input type="text" formControlName="name" class="form-control" placeholder="Full name"> <div *ngIf="submitted && f['name'].errors" class="alert alert-danger"> <div *ngIf="f['name'].errors.required">Full Name is required</div> </div>
This worked for me in Angular 7

So after two years, it has not been fixed? 🤣
related: https://github.com/angular/vscode-ng-language-service/issues/110

So after two years, it has not been fixed? 🤣
related: #110

It's not a bug, it's exactly the way it should work

If this is expected functionality, can the documentation be updated? (see here for one example).

This clearly infers the raw property accessors of ngModel can be used, where this thread has established they definitely cannot.

Actually is it fixed? I switched to hasError ages ago, but now I'm trying and failing to reproduce the error. myControl.errors.maxlength doesn't generate any red squiggly for me. This is with language service extension 0.801.1, which uses v8.1.x of the library, if that helps.

@thw0rted so, upon retest with myControl.errors.required and .pattern and (realized I missed the required attribute on the input tag, which was causing a bigger failure), they don't quite work.

Required mostly works, though there were some odd errors that popped up (missed capturing them and they're inconsistent unfortunately), and pattern fires when the pattern is wrong but doesn't seem to update when the pattern's correct.

Also, I have the same vsCode language extension, and I still see squigglies strangely.

Going to stick with .hasError solution for the moment, and probably would still recommend the docs get updated, at least to have that as a clearer/best practice use.

I found that this error appears every time you reference a property which is defined as 'any'. Another workaround is using the bracket property annotation, clientFirstName?.errors['required'] which is also pretty stupid.

This removed the errors for me. For reference, the code worked even when the errors were outlined, I just don't like seeing red lines in my code.

Yes putting in the key as a string removes the red lines.

But you lose features like correct spelling and auto-completion with this.

in addition to using hasError(), accessing a form's child control should use get() rather that dot access. e.g.

class MyComponent {
  form: FormGroup;
}

with lines like this in the template :

<app-errors [control]="form.controls.email">

Error message :

Identifier 'email' is not defined. '__type' does not contain such a member

solution would be:

<app-errors [control]="form.get('email')">

Same issue.

f.email.errors.email.required Fails
!!f.email.errors.email.required Fails
f.email?.errors.email.required Fails
f?.email?.errors.email.required Fails
f.email.error.['required'] Fails
f.email?.error.['required'] Fails

This worked for me:

f['email'].errors.required

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings