ngx-leaflet map zoom events not triggering - javascript

As per ngx-leaflet documentation link (leafletMapMoveEnd) and (leafletMapZoomEnd) are both exposed events.
I'm assuming that these events are exposed in the same DOM that the map is Initialized, and should be implemented like this:
<div
leaflet
[leafletOptions]="options"
(leafletMapReady)="onMapReady($event)"
(leafletMapMoveEnd)="onMapMove($event)"
(leafletMapZoomEnd)="onMapZoom($event)">
Is this the correct way to catch these events?
(leafletMapReady) seems to be working just fine.
However neither (leafletMapZoomEnd) or (leafletMapMoveEnd) seem to be triggering when I mess with the map it self.
I tried panning the map, as well as zooming in and out. Neither of those interactions cause the handleMapZoomEnd($event) handleMapMoveEnd($event) methods to be hit.
import { Component, Input, OnChanges, OnInit, Output, EventEmitter } from '#angular/core';
import * as fromLeafLet from 'leaflet';
import 'leaflet.markercluster';
#Component({
selector: 'map',
templateUrl: './map.component.html',
styleUrls: [
'./map.component.css',
'./extra-marker-icon.css'
]
})
export class MapComponent implements OnInit, OnChanges {
constructor(){}
onMapReady(map: fromLeafLet.Map): void {
this.map = map;
}
onMapZoom(event: any):void{
console.log('Zoom');
this.onMapDirty.emit();
}
onMapMove(event: any):void{
console.log('Move');
this.onMapDirty.emit();
}
}

In the Github repo for the #asymmetrik/ngx-leaflet ngcli tutorial, I added a branch demo/events that shows a really simple example of using the zoom/move events.
git clone git#github.com:Asymmetrik/ngx-leaflet-tutorial-ngcli.git
git checkout demo/events
The files of interest are:
./src/app/app.component.html
./src/app/app.component.ts
The template (below) contains two handlers, one for each of the leafletMapMoveEnd and leafletMapZoomEnd outputs:
<div class="map"
leaflet
[leafletOptions]="options"
(leafletMapReady)="onMapReady($event)"
(leafletMapMoveEnd)="handleMapMoveEnd($event)"
(leafletMapZoomEnd)="handleMapZoomEnd($event)"
></div>
The component (below) just prints to the console on these events. I removed mostly everything that's not necessary to demo the events working.
import { Component } from '#angular/core';
import * as L from 'leaflet';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [
'./app.component.css'
]
})
export class AppComponent {
streetMaps = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
detectRetina: true,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
});
map: L.Map;
options = {
layers: [ this.streetMaps ],
zoom: 7,
center: L.latLng([ 46.879966, -121.726909 ])
};
onMapReady(map: L.Map): void {
this.map = map;
}
handleMapZoomEnd(map: L.Map):void{
console.log('onMapZoomEnd');
}
handleMapMoveEnd(map: L.Map):void{
console.log('onMapMoveEnd');
}
}

Related

medium-zoom implementation is not working in Angular 13

I am trying to implement medium-zoom from https://www.npmjs.com/package/medium-zoom
These are the steps I followed
ng new medium_zoom_test (Angular 13) with routing & css
npm install medium-zoom
image is kept in assets
app.component.html
<h1>Zoom test</h1>
<img class="zoomy" width="50%" src="assets/image.svg">
app.component.ts
import { Component } from '#angular/core';
import mediumZoom from 'medium-zoom';
mediumZoom('.zoomy', {
margin: 40,
background: '#ffffff',
scrollOffset: 40
})
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'medium_zoom_test';
}
On serving the application the webpage with image is visible. However, there's no zoom icon on hover and the image won't zoom on click. It's just a normal webpage with no change.
Any alternatives to implement the zooming of images are welcome too.
I don't think mediumZoom will work when the passed selector has no corresponding element in the DOM. What I mean is where you call mediumZoom function the component is not attached to the DOM yet. If you want to guarantee that you need to call it on ngOnInit lifecycle hook. Or you can do better which is to define a directive that applies the zoom affect like this :
import mediumZoom from 'medium-zoom';
#Directive({
selector: '[appZoomie]'
})
export class ZoomieDirective {
constructor(private el: ElementRef) {
mediumZoom(el.nativeElement, {
margin: 40,
background: '#ffffff',
scrollOffset: 40
})
}
}
And use it like this :
<img appZoomie src=".."/>
Stackblitz

preprocess: ERROR could not parse #Component() metadata path/to/my.component.ts

I have updated my angular project to Angular v11 which successfully updated. This brought a warning that TSLint is deprecated and following the steps outlined Here - Migrating from Codelyzer and TSLint I managed to migrate this.
After this update, I received several errors which I have an idea of how to solve, except this one error
Error: Debug Failure. False expression: position cannot precede the beginning of the file
at computeLineOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8934:22)
at computeLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8912:26)
at Object.getLineAndCharacterOfPosition C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8953:16)
at SourceFileObject.getLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:143309:23)
at preprocess (C:\Path\to\Project\node_modules\#angular-eslint\eslint-plugin-template\dist\index.js:1:1430)
at Linter._verifyWithProcessor (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1292:30)
at Linter._verifyWithConfigArray (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1264:25)
at Linter.verify (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1226:25)
at Linter.verifyAndFix (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1416:29)
at verifyText (C:\Path\to\Project\node_modules\eslint\lib\cli-engine\cli-engine.js:239:48)
preprocess: ERROR could not parse #Component() metadata C:\Path\to\Project\src\app\components\label-star-required\label-star-required.component.ts
Error: Debug Failure. False expression: position cannot precede the beginning of the file
at computeLineOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8934:22)
at computeLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8912:26)
at Object.getLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8953:16)
at SourceFileObject.getLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:143309:23)
at preprocess (C:\Path\to\Project\node_modules\#angular-eslint\eslint-plugin-template\dist\index.js:1:1430)
at Linter._verifyWithProcessor (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1292:30)
at Linter._verifyWithConfigArray (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1264:25)
at Linter.verify (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1226:25)
at Linter.verifyAndFix (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1416:29)
at verifyText (C:\Path\to\Project\node_modules\eslint\lib\cli-engine\cli-engine.js:239:48)
preprocess: ERROR could not parse #Component() metadata C:\Path\to\Project\src\app\components\skip-link\skip-link.component.ts
Below are the two components throwing this error
label-star-required.component.ts
import {Component} from '#angular/core';
#Component({
selector: 'app-label-star-required',
templateUrl: './label-star-required.component.html',
styleUrls: ['./label-star-required.component.css']
})
export class LabelStarRequiredComponent {
constructor() {
}
}
#Component({
selector: 'app-star-required',
template: `
<span class='icon-star required'></span>
`,
styleUrls: ['./label-star-required.component.css']
})
export class StarRequiredComponent {
constructor() {
}
}
skip-link.component.ts
import { Component, OnInit, OnDestroy } from '#angular/core';
import { Router, NavigationStart } from '#angular/router';
import { filter, takeWhile, map } from 'rxjs/operators';
#Component({
selector: 'app-skip-link',
styleUrls: ['./skip-link.component.css'],
template: `
<a [href]="skipLinkPath" class="skip-main">Skip to main content</a>
`
})
export class SkipLinkComponent implements OnInit, OnDestroy {
skipLinkPath: string;
componentIsActive: boolean;
constructor(
private router: Router
) { }
ngOnInit() {
this.componentIsActive = true;
this.skipLinkPath = `${this.router.url.replace('#main', '')}#main`;
this.router.events.pipe(filter(event => event instanceof NavigationStart))
.pipe(takeWhile(() => this.componentIsActive))
.pipe(map(event => (event as any).url ))
.subscribe(url => {
if (!/(.)#main$/.test(url)) {
this.skipLinkPath = `${url}#main`;
}
});
}
ngOnDestroy() {
this.componentIsActive = false;
}
}
From the above two components, I can see that the common similarity is that both the files are using
inline template: . Might this be causing the error while running ng lint ? How do I solve this?
My workaround was to move the html code in the component template to templateUrl.
#Component({
selector: 'app-star-required',
template: `<span class='icon-star required'></span>`,
styleUrls: ['./label-star-required.component.css']
})
Becomes
#Component({
selector: 'app-star-required',
templateUrl: './label-star-required.component.html',
styleUrls: ['./label-star-required.component.css']
})
Seems to be a bug with ESlint/Angular configuration.
As a workaround, i added "endOfLine": "lf" to my prettier config which fixed the issue after reformatting the project.
See https://github.com/angular-eslint/angular-eslint/issues/185
I noticed this error too with templates that had escaped double quotes in them:
template: "<div class=\"my-class\"></div><ng-content></ng-content>"
I solved it by switching to single quotes:
template: "<div class='my-class'></div><ng-content></ng-content>"

How to define JitsiMeetExternalAPI in angular 8

I'm using jisti application to implement video call in angular 8,am not understanding JitsiMeetExternalAPI how to define this. please help me on this.(Am getting error as error TS2304: Cannot find name 'JitsiMeetExternalAPI'.).
Simply add this line to app.component.ts.
declare var JitsiMeetExternalAPI: any;
In my case, it worked fine.
Finally, the code looks like this.
import { Component, AfterViewInit } from '#angular/core';
import '../vendor/jitsi/external_api.js';
declare var JitsiMeetExternalAPI: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'sidenav';
domain: string = "meet.jit.si";
options: any;
api: any;
constructor() {
}
ngAfterViewInit(): void {
this.options = {
roomName: "JitsiMeetAPIExample",
width: 700,
height: 700,
parentNode: document.querySelector('#meet')
}
this.api = new JitsiMeetExternalAPI(this.domain, this.options);
}
}
I was facing the same issue and solved by pointing to the script in angular.json like the following ...
"scripts": ["src/vendor/jitsi/external_api.js"]
I had to download and copy the https://meet.jit.si/external_api.js script onto "src/vendor/jitsi" directory of my angular code.

Ionic 3 Google Maps Integration

I am following this tutorial exactly: https://www.djamware.com/post/58f4da2080aca7414e78a638/step-by-step-tutorial-of-ionic-3-angular-4-and-google-maps-directions-service
But I cannot get it to work. I have the API key set up no problem, but for some reason I keep getting the error Error: Uncaught (in promise): ReferenceError: google is not defined
ReferenceError: google is not defined
I am running the app using ionic lab
For some reason it isn't working. Can someone help me find the problem? I have tried adding the cordova whitelist plugin, changing the https to http in the API key part, but still it isn't working.
Did you declare the variable at home.ts?
import { Component, ViewChild, ElementRef } from '#angular/core';
import { IonicPage } from 'ionic-angular';
import { NavController } from 'ionic-angular';
declare var google;
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
...
Ionic 3 Google Map click doc link
1.install this package
$ ionic cordova plugin add https://github.com/mapsplugin/cordova-plugin-googlemaps#multiple_maps --variable API_KEY_FOR_ANDROID="YOUR_ANDROID_API_KEY_IS_HERE" --variable API_KEY_FOR_IOS="YOUR_IOS_API_KEY_IS_HERE"
$ npm install --save #ionic-native/google-maps
2.Android and ios Api create
Go to this site - google cloud platform
3.After you got Api install packages
4.import
app.module.ts
import { GoogleMaps } from '#ionic-native/google-maps';
......
provider:[
GoogleMaps
];
5.home.html
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div id="map"></div>
</ion-content>
6.home.ts
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import {
GoogleMaps,
GoogleMap,
GoogleMapsEvent,
LatLng,
CameraPosition,
MarkerOptions,
Marker
} from '#ionic-native/google-maps';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController,
private googleMaps: GoogleMaps,
public platform: Platform) {
platform.ready().then(()=>{
this.loadMap();
})
}
loadMap() {
// create a new map by passing HTMLElement
let element: HTMLElement = document.getElementById('map');
let map: GoogleMap = this.googleMaps.create(element);
// listen to MAP_READY event
// You must wait for this event to fire before adding something to the map or modifying it in anyway
map.one(GoogleMapsEvent.MAP_READY).then(
() => {
console.log('Map is ready!');
// Now you can add elements to the map like the marker
}
);
// create CameraPosition
let position: CameraPosition = {
target: {
lat: 43.0741904,
lng: -89.3809802
},
zoom: 18,
tilt: 30
};
// move the map's camera to position
map.moveCamera(position);
// create new marker
let markerOptions: MarkerOptions = {
//position: ionic,
title: 'Ionic'
};
map.addMarker(markerOptions)
.then((marker: Marker) => {
marker.showInfoWindow();
});
}
}

Angular2 fire click event on unknown html element

I want to handle a click event of x3dom's shape html element in my parent component. The onclick event is fired by x3dom. I can only delegate it with an ugly hack (see below).
Because shape is not a known Html tag by Angular 2 I have to define ashape component? or Not?
In Parent Component:
<shape (click)="doStuffInParent()" ></shape> <!-- click is not fired by x3dom -->
Shape component so far:
import {Component} from '#angular/core';
import { Input, Output, EventEmitter} from '#angular/core';
#Component({
selector: 'Shape',
providers: [],
directives: [],
pipes: []
})
export class Shape {
#Output() notify: EventEmitter<string> = new EventEmitter<string>(); // wrong!
constructor() {}
}
Edit: Maybe I don't need the component? The onclick event is fired by X3dom and not by me.
another solution for me would be if I can just call my component method from a regular onclick event what I asked here.
Update I hacked a solution what solved at least my problem:
call Angular 2 component method from html event
Working Demo : https://plnkr.co/edit/qQudgi9touIFOe52m4JY?p=preview
<Shape (myClick)="doStuffInParent($event)"></Shape>
in Component code,
doStuffInParent(value){
console.log(value); //Angular2
}
import {Component} from '#angular/core';
import { Input, Output, EventEmitter} from '#angular/core';
#Component({
selector: 'Shape',
providers: [],
directives: [],
pipes: [],
template:`<div (click)="click()">Shap Component</div>`
})
export class Shape {
#Output() myClick: EventEmitter<string> = new EventEmitter<string>();
click(){
this.myClick.next('Angular2');
}
}

Categories