I'm working on an Ionic 3 project and for map related functionality, I chose Google Maps plugin suggested by Ionic Team. The Google Maps Ionic plugin is basically a wrapper around cordova-plugin-googlemaps. I've followed the steps mentioned in this presentation.
I'm not able to show map in element with id map_canvas, which is placed in one of page html. Here's what I've tried so far:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { GoogleMaps, GoogleMap, Marker } from '#ionic-native/google-maps';
#IonicPage()
#Component({
selector: 'page-step-two',
templateUrl: 'step-two.html',
})
export class StepTwoPage {
private stepTwoForm: FormGroup;
private map: GoogleMap;
constructor(private formBuilder: FormBuilder) {
this.stepTwoForm = this.formBuilder.group({
prename: ['', Validators.required],
name: ['', Validators.required],
email: ['', Validators.required],
mobile: ['', Validators.required],
yearLiving: ['', Validators.required],
});
}
ionViewDidLoad() {
// Create a map after the view is ready
// and the native platform is ready.
this.loadMap();
}
loadMap() {
this.map = GoogleMaps.create('map_canvas'); // <--- Problematic statement
}
goToStepThree() {
}
}
And here's page html:
<ion-header>
<ion-navbar>
<ion-title>Step - 2</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<progress-bar [stepCount]="5" [currentStep]="2"></progress-bar>
<ion-card class="step-body-card">
<ion-card-header>
<h1 text-center class="card-title">Persona</h1>
</ion-card-header>
<ion-card-content>
<form [formGroup]="stepTwoForm" (ngSubmit)="goToStepThree()">
<ion-grid>
<ion-row>
<ion-col col-12 col-sm>
<ion-item>
<ion-input type="text" placeholder="Prename" formControlName="prename"></ion-input>
</ion-item>
</ion-col>
<ion-col col-12 col-sm>
<ion-item>
<ion-input type="text" placeholder="Name" formControlName="name"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-12 col-sm>
<ion-item>
<ion-input type="email" placeholder="Email" formControlName="email"></ion-input>
</ion-item>
</ion-col>
<ion-col col-12 col-sm>
<ion-item>
<ion-input type="tel" placeholder="Mobile" formControlName="mobile"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-12 col-sm>
<ion-item>
<ion-input type="number" min="0" placeholder="Year of living" formControlName="yearLiving"></ion-input>
</ion-item>
</ion-col>
<ion-col col-12 col-sm>
</ion-col>
</ion-row>
</ion-grid>
<button margin-top ion-button type="submit" [disabled]="!stepTwoForm.valid">Continue</button>
</form>
</ion-card-content>
</ion-card>
</ion-content>
I tried running in Android and it gives an error, without anyhting being shown on map_canvas element. The error is produced by cordova:
Error in Success callbackId: CordovaGoogleMaps1188158820 : ReferenceError: element is not defined
And here's stack-trace from console:
Uncaught ReferenceError: element is not defined
at Map.<anonymous> (:8100/plugins/cordova-plugin-googlemaps/www/CordovaGoogleMaps.js:645)
at Map.trigger (:8100/plugins/cordova-plugin-googlemaps/www/BaseClass.js:68)
at Map.set (:8100/plugins/cordova-plugin-googlemaps/www/BaseClass.js:35)
at Map.getMap (:8100/plugins/cordova-plugin-googlemaps/www/Map.js:152)
at :8100/plugins/cordova-plugin-googlemaps/www/CordovaGoogleMaps.js:881
at Object.callbackFromNative (cordova.js:291)
at <anonymous>:1:9
I can confirm that this error is produced by statement while initializing or creating map, pointed out as Problematic statement in page.ts. I'm unable to get the underlying problem for this error.
Please help me troubleshooting the problem and suggest fix.
EDIT
After debugging I found out that the error only occurs if the map_canvas element (div) is inside the form, if I take it out of the form tag, it works as expected and map shows.
Maybe this is a bug or something is wrong with FormBuilder. I need to show Google Map inside form, so please help me fixing this odd behavior of Google Map plugin. Edited question which includes full form for reference now and simplified map creation logic.
Update
After building shared project, I can not reproduce the error
The problem has been gone at least v2.3.8
Related
I want that the user can choose only one tag. So the button should be disabled after the user has pushed one tag to the list. So I made up the idea that if the list.length is bigger than 0, the button should be disabled. But somehow it doesn't work in my approach.
page.html
<ion-item>
<ion-input mode="md" formControlName="category" clearInput="true" placeholder="Tag" name="tagValue"></ion-input>
<ion-button [disabled]="!categoryForm.valid" [disabled]="tagList?.length > 1" item-right type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>
page.ts
public tagInput: string = '';
public tagList: any[] = [];
constructor() {}
...
addTag() { // properly access and reset reactive form values
const tagCtrl = this.categoryForm.get('category');
if (tagCtrl.value) {
this.tagList.push(tagCtrl.value);
this.tagInput = ''; // in order to have an empty input
}
}
You're using disable attribute twice:
<ion-item>
<ion-input mode="md" formControlName="category" clearInput="true" placeholder="Tag" name="tagValue"></ion-input>
<ion-button [disabled]="!categoryForm.valid || tagList?.length > 0" item-right type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>
I want to do a simple if else in Angular template. I'm using Ionic framework. What I want to do is something like
if (val != null){
document.write("No value");
}
else{
document.write("Has value");
}
What I have now is
<ion-grid *ngIf="devices">
<!-- Show if devices exist -->
<ion-row>
<ion-col>
<ion-list>
<ion-item>
device 1
</ion-item>
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
<ion-grid>
<!-- Show if devices DO NOT exist -->
<ion-row>
<ion-col>
<button text-center ion-button round col-6 offset-3> Odśwież urządznia </button>
</ion-col>
</ion-row>
</ion-grid>
I wanted to do something like *ngIf!=null or *ngElse but these two do not work.
So my question is how do I do that?
You have to use in following way -
<div *ngIf="condition; else elseBlock">
Truthy condition
</div>
<ng-template #elseBlock>
False condition
</ng-template>
hope this will help you, let me know in case any issue?
I am working with dynamic ion-input, there are two fields, which will be shown to the user and the user can add or remove fields.
The maximum is five fields and minimum is two. I have another input, which I can validate properly for required validation, but how can I validate dynamically added fields at runtime, which can be 2, 3, 4 or 5?
My code, for which I have done validation and the dynamic field are below. Can anyone please help me to resolve this?
single input field
<div text-center [formGroup]="pollQuesValid">
<ion-item>
<ion-input type="text" formControlName="questTxt" [(ngModel)]="question">
</ion-input>
</ion-item>
<ion-item *ngIf="!pollQuesValid.controls.questTxt.valid && submitAttemptQues" text-center text-wrap no-lines>
<p style="color: red">{{"quesValid" | translate }}</p>
</ion-item>
</div>
pollQuesValid: FormGroup;
submitAttemptQues: boolean = false;
this.pollQuesValid = formBuilder.group({
questTxt: ["", ([Validators.required])]
});
if (this.pollQuesValid.controls.questTxt.valid) {
this.submitAttemptQues = false;
console.log("question valid");
return true;
} else {
this.submitAttemptQues = true;
console.log('question invalid');
return false;
}
dynamic fields
<div>
<ion-item *ngFor="let choice of custOpts; let i = index;">
<ion-label color="primary" floating>{{choice.hint}} {{i+1}}</ion-label>
<ion-input type="text" [(ngModel)]="choice.ch"></ion-input>
<ion-icon class="remove" item-end name="md-remove" *ngIf="i>=2" (click)="removecustOpts()"></ion-icon>
</ion-item>
<div *ngIf="custOpts.length < 5" padding>
<button ion-button icon-only (click)="addNewChoice()">
<ion-icon name="md-add"></ion-icon>
</button>
</div>
</div>
You can use FomrArray to dynamically add and validate FormGroup or FormControl in a reactive form.FormArray become invalid if any one of the controls inside it is invalid (angular docs).
First, define the form and initial two fields
pollQuesValid: FormGroup;
customOptions: FormArray;
this.pollQuesValid = new FormGroup({
questTxt: new FormControl('question text', Validators.required),
options: new FormArray([
new FormControl('',Validators.required),
new FormControl('',Validators.required),
])
});
this.customOptions = this.pollQuesValid.get('options') as FormArray; //for iterating dynamic fields using *ngFor
Then change the html markup of dynamic fields like this
<div text-center [formGroup]="pollQuesValid">
...
<div formArrayName="options">
<ion-item *ngFor="let choice of customOptions.controls; let i = index;">
<ion-label color="primary" floating>Hint {{i+1}}</ion-label>
<ion-input type="text" [formControlName]="i"></ion-input>
<ion-icon class="remove" item-end name="md-remove" *ngIf="i>=2" (click)="removecustOpts(i)"></ion-icon>
</ion-item>
<div *ngIf="customOptions.controls.length < 5" padding>
<button ion-button icon-only (click)="addNewChoice()">
<ion-icon name="md-add"></ion-icon>
</button>
</div>
</div>
</div>
Here is a working StackBlitz example (pages/home).
I have a side project in Ionic 3. In this project I have view with array of users, this works perfectly. These users have a button with id, when we click we move to other view to show more data of this user. All backend is Lumen and tested with Postman, response is correct.
The problem that I have is that the second page doesn´t show any data, but I check in network tab and receive the json correctly. When I go back to first page and go again to the second page, data see in the view. ¿Why the first time that I go to the second page the data doesn´t appear? I think that is a strange error.
data2: any
verDetalles(id:any){
this.visitantes.verVisitante(id)
.then(data2 => {
this.data2 = Array(data2);
});
this.navCtrl.push(DatosPreVisitasPage, {
animate: true,
data:this.data2
});
}
//CALL TO ENDPOINT
verVisitante(id:any) {
return this.http.get('http://visitas.api.app:8000/visitantes/'+id)
.map(res => res.json())
.toPromise();
}
And this code in view
<ion-header >
<ion-navbar>
<ion-title text-center>
Datos Prevista
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding class="background">
<ion-grid >
<ion-card padding>
<ion-list *ngFor="let user of datos" >
<ion-item>
<ion-label floating>Nombre</ion-label>
<ion-input type="text" [(ngModel)]="user.nombre" name="nombre"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Apellido</ion-label>
<ion-input type="text" [(ngModel)]="user.apellidos" name="apellido"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Empresa</ion-label>
<ion-input type="text" [(ngModel)]="user.empresa" name="empresa"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>DNI</ion-label>
<ion-input type="text" [(ngModel)]="user.dni" name="dni"></ion-input>
</ion-item>
</ion-list>
</ion-card>
</ion-grid>
</ion-content>
Maybe is a error on the promise or something like that, but not sure, i'm new in ionic.
You should call the second page inside .then so that it is called only when data has aarrived:
data2: any
verDetalles(id:any) {
this.visitantes.verVisitante(id)
.then(data2 => {
this.data2 = Array(data2);
this.navCtrl.push(DatosPreVisitasPage, {
animate: true,
data:this.data2
});
});
}
I'm making an template for an app, and i need to show a select component when one of the previous radio buttons is set in a determined state. The logic is this:
The current code I have got is this:
<ion-row>
<ion-list radio-group [(ngModel)]="tipo">
<ion-item>
<ion-label>Gato</ion-label>
<ion-radio value="g" checked></ion-radio>
</ion-item>
<ion-item>
<ion-label>Perro</ion-label>
<ion-radio value="p"></ion-radio>
</ion-item>
</ion-list>
<div ng-if="tipo === 'g'">
<ion-list>
<ion-item>
<ion-label>Choose</ion-label>
<ion-select [(ngModel)]="raza1">
<ion-option value="angora">angora</ion-option>
<ion-option value="persa">persa </ion-option>
</ion-select>
</ion-item>
</ion-list>
</div>
<div ng-if="tipo === 'p'">
<ion-list>
<ion-item>
<ion-label>Choose</ion-label>
<ion-select [(ngModel)]="raza2">
<ion-option value="pastor aleman">Pastor Aleman</ion-option>
<ion-option value="schnauzer">schnauzer</ion-option>
</ion-select>
</ion-item>
</ion-list>
</div>
</ion-row>
So long I haven't reached the ng-if to work and I don't know why. If you could help me figure out why. Thanks
Most of the time, these kind of issues are related to javascript references. instead of
$scope.tipo, use
$scope.someNamespace = {
tipo: ''
};
then use someNamespace.tipo instead of tipo in html