ChatGPT解决这个技术问题 Extra ChatGPT

Angular @ViewChild() error: Expected 2 arguments, but got 1

When trying ViewChild I am getting the error. Error is "An argument for 'opts' was not provided."

Both @ViewChild is giving the error.

import { Component, OnInit, ElementRef, ViewChild, Output, EventEmitter } from '@angular/core';
import { Ingredient } from 'src/app/shared/ingredient.model';

@Component({
  selector: 'app-shopping-edit',
  templateUrl: './shopping-edit.component.html',
  styleUrls: ['./shopping-edit.component.css']
})
export class ShoppingEditComponent implements OnInit {

@ViewChild('nameInput') nameInputRef: ElementRef;
@ViewChild('amountInput') amountInputRef: ElementRef;
@Output() ingredientAdded = new EventEmitter<Ingredient>();
  constructor() {}

  ngOnInit() {
  }

  onAddItem() {
    const ingName = this.nameInputRef.nativeElement.value;
    const ingAmount = this.amountInputRef.nativeElement.value;
    const newIngredient = new Ingredient(ingName, ingAmount);
    this.ingredientAdded.emit(newIngredient);
  }

}

ts(11,2): error TS2554: Expected 2 arguments, but got 1.

What is in line 11 ?
@TonyNgo @ViewChild('nameInput') nameInputRef: ElementRef;

J
Jensen

In Angular 8 , ViewChild takes 2 parameters

 @ViewChild(ChildDirective, {static: false}) Component

can you please mark it as accepted? From Angular docs: static - whether or not to resolve query results before change detection runs (i.e. return static results only). If this option is not provided, the compiler will fall back to its default behavior, which is to use query results to determine the timing of query resolution. If any query results are inside a nested view (e.g. *ngIf), the query will be resolved after change detection runs. Otherwise, it will be resolved before change detection runs.
You should add that to the answer if you want him to accept your answer as the best one
Note: to keep the behavior you had in Angular 7, you need to specify { static: true }. ng update will help you do this automatically where needed. Or, if you've already upgraded your dependencies to Angular 8, this command will help migrate your code: ng update @angular/core --from 7 --to 8 --migrate-only
If the element needs to be available during ngOnInit, then static needs to be true, but if it can wait until after the init it can be false, which means it won't be available until ngAfterViewInit/ngAfterContentInit.
I didn't know that. Thanks. :-)
R
Reza

Angular 8

In Angular 8, ViewChild has another param

@ViewChild('nameInput', {static: false}) component : Component

You can read more about it here and here

Angular 9 & Angular 10

In Angular 9 default value is static: false, so doesn't need to provide param unless you want to use {static: true}


In one of the articles you linked to, they show syntax like @ContentChild('foo', {static: false}) foo !: ElementRef;. I'm curious about the exclamation mark. Is that something new with Angular 8 too?
@KonradViltersten see this stackoverflow.com/a/56950936/2279488
F
Fouad Boukredine

In Angular 8 , ViewChild takes 2 parameters:

Try like this:

@ViewChild('nameInput', { static: false }) nameInputRef: ElementRef;

Explanation:

{ static: false }

If you set static false, the child component ALWAYS gets initialized after the view initialization in time for the ngAfterViewInit/ngAfterContentInit callback functions.

{ static: true}

If you set static true, the child component initialization will take place at the view initialization at ngOnInit

By default you can use { static: false }. If you are creating a dynamic view and want to use the template reference variable, then you should use { static: true}

For more info, you can read this article

Working Demo

In the demo, we will scroll to a div using template reference variable.

 @ViewChild("scrollDiv", { static: true }) scrollTo: ElementRef;

With { static: true }, we can use this.scrollTo.nativeElement in ngOnInit, but with { static: false }, this.scrollTo will be undefined in ngOnInit , so we can access in only in ngAfterViewInit


p
paras shah

it is because view child require two argument try like this

@ViewChild('nameInput', { static: false, }) nameInputRef: ElementRef; @ViewChild('amountInput', { static: false, }) amountInputRef: ElementRef;


P
Pinki Dhakad

In Angular 8, ViewChild always takes 2 param, and second params always has static: true or static: false

You can try like this:

@ViewChild('nameInput', {static: false}) component

Also,the static: false is going to be the default fallback behaviour in Angular 9.

What are static false/true: So as a rule of thumb you can go for the following:

{ static: true } needs to be set when you want to access the ViewChild in ngOnInit. { static: false } can only be accessed in ngAfterViewInit. This is also what you want to go for when you have a structural directive (i.e. *ngIf) on your element in your template.


p
prosoitos

Try this in angular 8.0:

@ViewChild('result',{static: false}) resultElement: ElementRef;

this question is one year old, but you has reason, in Angular 8.0 was neccesary {static:true/false}. In Angular 9 and 10 this argument is optional
T
Torsten Simon

Regex for replacing all via IDEA (tested with Webstorm)

Find: \@ViewChild\('(.*)'\)

Replace: \@ViewChild\('$1', \{static: true\}\)


H
Hammad Ahmad

you should use second argument with ViewChild like this:

@ViewChild("eleDiv", { static: false }) someElement: ElementRef;

D
Dhilrukshan Pradeep

Use this

@ViewChild(ChildDirective, {static: false}) Component


M
Manoj Tyagi

In Angular 8, ViewChild has another param

@ViewChild('nameInput', {static: false}) component

I resolved my issue like below

@ViewChild(MatSort, {static: false}) sort: MatSort;


A
Arsman Ahmad

That also resolved my issue.

@ViewChild('map', {static: false}) googleMap;

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now