An argument for 'opts' was not provided

ERROR in src/app/bookings/create-booking/create-booking.component.ts:15:4 - error TS2554: Expected 2 arguments, but got 1.
[ng] 15 @ViewChild(‘f’) form: NgForm;
[ng] ~~~~~~~~~~~~~~
[ng] node_modules/@angular/core/core.d.ts:8436:47
[ng] 8436 (selector: Type | Function | string, opts: {
[ng] ~~~~~~~
[ng] 8437 read?: any;
[ng] ~~~~~~~~~~~~~~~~~~~
[ng] 8438 static: boolean;
[ng] ~~~~~~~~~~~~~~~~~~~~~~~~
[ng] 8439 }): any;
[ng] ~~~~~
[ng] An argument for ‘opts’ was not provided.
[ng]

RTFM?

Breaking change as of angular 8. Two arguments needed nowadays on a viewchild

RTM

ANSWER HERE: import { Component, OnInit, Input, ViewChild } from ‘@angular/core’; import { ModalController } from ‘@ionic/angular’; import { NgForm } from ‘@angular/forms’; import { Place } from ‘…/…/places/place.model’; @Component({ selector: ‘app-create-booking’, templateUrl: ‘./create-booking.component.html’, styleUrls: [’./create-booking.component.scss’] }) export class CreateBookingComponent implements OnInit { @Input() selectedPlace: Place; @Input() selectedMode: ‘select’ | ‘random’; @ViewChild(‘f’, { static: true }) form: NgForm;

Reason for this code:

That is because of breaking change in new Angular. A new static flag has been introduced to not break existing applications, so if you want to keep the old behavior even when you’ll switch to Ivy, you can write: @ViewChild(‘f’, { static: true }) form: NgForm;

You can further read here : angular.io/api/core/ViewChild#description

Answer Explanation my instructor: https://www.udemy.com/user/jost-schmithals/

In Angular 8 (but not before and after) we have to use this special syntax for @ViewChild:

Instead of …

  1. @ViewChild(‘myInput’) myInput: ElementRef;

… we have to use in Angular 8 …

  1. @ViewChild(‘myInput’, {static: true}) myInput: ElementRef;

This change (add { static: true } as a second argument) needs to be applied to all usages of @ViewChild() if we plan on accessing the selected element inside of ngOnInit() .

If we don’t access the selected element in ngOnInit (but anywhere else in our component), we have to set { static: false } instead.

This is a temporary adjustment which will NOT be required anymore once Angular 9 is released.

Detailed explanations:

https://angular.io/guide/static-query-migration


This being said:

If you have written it without { static: true/false } in spite of using Angular 8, you should actually have gotten a more explicit error message for @ViewChild: " Expected 2 arguments, but got 1 ".

2 Likes

this is my solution on my Ionic-Angular App
https://mytopcountries.web.app/tabs/home

import {AfterViewInit, Component, OnInit, Input, ElementRef, NgZone, ViewChild } from ‘@angular/core’;
import {Geolocation} from ‘@ionic-native/geolocation/ngx’;

import { Events, IonContent, NavController } from ‘@ionic/angular’;

declare var google: any;

@Component({
selector: ‘app-places’,
templateUrl: ‘./places.page.html’,
styleUrls: [’./places.page.scss’],
})
export class PlacesPage {

@ViewChild(‘Map’, {static: true}) mapElement: ElementRef;
Map: any;
mapOptions: any;
location = {lat: null, lng: null};
markerOptions: any = {position: null, map: null, title: null};
marker: any;
apiKey: any = ‘’; /Your API Key/

constructor(public zone: NgZone, public geolocation: Geolocation) {
/*load google map script dynamically */
const script = document.createElement(‘script’);
script.id = ‘googleMap’;
if (this.apiKey) {
script.src = ‘https://maps.googleapis.com/maps/api/js?key=’ + this.apiKey;
} else {
script.src = ‘https://maps.googleapis.com/maps/api/js?key=’;
}
document.head.appendChild(script);
/Get Current location/
this.geolocation.getCurrentPosition().then((position) => {
this.location.lat = position.coords.latitude;
this.location.lng = position.coords.longitude;
});
/Map options/
this.mapOptions = {
center: this.location,
zoom: 8,
mapTypeControl: false
};
setTimeout(() => {
this.Map = new google.maps.Map(this.mapElement.nativeElement, this.mapOptions);
/Marker Options/
this.markerOptions.position = this.location;
this.markerOptions.map = this.Map;
this.markerOptions.title = ‘My Location’;
this.marker = new google.maps.Marker(this.markerOptions);
}, 3000);
}

}