How to include jQuery Plugin Mapael into Angular 5? - javascript

So, I tried following a bit how other questions dealt with the problem of including jQuery Plugins. But let's start with the basics first.
First, I installed the jQuery plugin.
npm i jquery
Then, I added the typescript definition.
npm install -d #types/jquery
I included it in my script array.
"apps": [{
...
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
],
...
}]
Then, I tried out if it works.
import { Component, OnInit} from '#angular/core';
import * as $ from 'jquery';
#Component({
selector: 'app-ww-inventory-map',
templateUrl: './ww-inventory-map.component.html',
styleUrls: ['./ww-inventory-map.component.scss']
})
export class WwInventoryMapComponent implements OnInit {
constructor() { }
ngOnInit() {
$(window).click(function () {
alert('ok');
});
}
}
The response came promptly...
So far, so good. First work-package is done, time to continue. I installed then the jQuery plugin mapael
npm i jquery-mapael
angular-cli.json
"apps": [{
...
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/jquery-mapael/js/jquery.mapael.min.js",
"../node_modules/jquery-mousewheel/jquery.mousewheel.js"
],
...
}]
After that I tried this. Based on the code example seen on the official page
https://www.vincentbroute.fr/mapael/#basic-code-example
import { Component, OnInit } from '#angular/core';
import * as $ from 'jquery';
declare global {
interface JQuery {
mapael(map: any): JQuery;
}
}
#Component({
selector: 'app-ww-inventory-map',
templateUrl: './ww-inventory-map.component.html',
styleUrls: ['./ww-inventory-map.component.scss']
})
export class WwInventoryMapComponent implements OnInit {
constructor() { }
ngOnInit() {
$(".container").mapael({
map: {
name: "world_countries"
}
});
}
}
At first things looked fine, no warnings or problems shown, but when I load the page...
So, I'm at loss how to do this properly. I was hoping that I could fix this somehow. But none of the other few examples have been of much help to me. I apologize, knowing that there have been similar questions, but I can't really get it to work.
EDIT 1: The first solution I tried out was from Naga Sai A, but - on my end - it requires some changes, so the compiler won't complain. Thanks, Naga Sai A!
My .ts looks right this
import { Component, OnInit } from '#angular/core';
import * as $ from 'jquery';
import 'jquery-mapael';
import 'jquery-mapael/js/maps/world_countries.js';
declare global {
interface JQuery {
mapael(map: any): JQuery;
}
}
#Component({
selector: 'app-ww-inventory-map',
templateUrl: './ww-inventory-map.component.html',
styleUrls: ['./ww-inventory-map.component.scss']
})
export class WwInventoryMapComponent implements OnInit {
constructor() { }
ngOnInit() {
$(".container").mapael({
map: {
name: "world_countries"
}
});
}
}
EDIT 2: Placeholder for Peters solution
The imports are correct, but the component still require the imports. Also, including Raphael.js is NOT required. At least I didn't and the map works splendidly. My setup hasn't changed. Also, I kept my initial way of declaration.

The main issue is with your script imports. You are not importing a required dependency for Raphael. Also, you need to import any maps you plan on using. Update your angular-cli.json to the following:
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/raphael/raphael.min.js",
"../node_modules/jquery-mousewheel/jquery.mousewheel.js",
"../node_modules/jquery-mapael/js/jquery.mapael.min.js",
"../node_modules/jquery-mapael/js/maps/world_countries.min.js"
],
Note from NPM:
Note on dependencies: jQuery and Raphael (and Mousewheel, if needed) must be loaded before Mapael in order to work properly.
Note on maps: map files must be loaded after Mapael in order to work properly.
https://www.npmjs.com/package/jquery-mapael#directly-in-your-page
import { Component, OnInit } from '#angular/core';
//jquery declaration
declare var $: any;
#Component({
selector: 'app-ww-inventory-map',
templateUrl: './ww-inventory-map.component.html',
styleUrls: ['./ww-inventory-map.component.scss']
})
export class WwInventoryMapComponent implements OnInit {
constructor() { }
ngOnInit() {
$(".container").mapael({
map: {
name: "world_countries"
}
});
}
}

To achieve expected result, use below option of importing jquery, jquery-mapael and js for world countries map
import * as $ from 'jquery';
import 'jquery-mapael';
import 'jquery-mapael/js/maps/world_countries.js';
and in ngOnInit
ngOnInit() {
$(".container").mapael({
map: {
name: "world_countries"
}
});
}
It works as shown in screenshot

Related

ERROR TypeError: jquery__WEBPACK_IMPORTED_MODULE_0__(...).show().revolution is not a function

I am learning Angular. I am trying to integrate Revolution Slider in Angular 11 WebSite. Script section of my angular.json file is like below.
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"src/assets/js/bootstrap.min.js",
"src/assets/js/modernizr.custom.js",
"src/assets/js/gmaps.js",
"src/assets/js/jquery.themepunch.revolution.min.js",
"src/assets/js/jquery.themepunch.tools.min.js",
"src/assets/js/extensions/revolution.extension.actions.min.js",
"src/assets/js/extensions/revolution.extension.carousel.min.js",
"src/assets/js/extensions/revolution.extension.kenburn.min.js",
"src/assets/js/extensions/revolution.extension.migration.min.js",
"src/assets/js/extensions/revolution.extension.parallax.min.js",
"src/assets/js/extensions/revolution.extension.slideanims.min.js",
"src/assets/js/extensions/revolution.extension.layeranimation.min.js",
"src/assets/js/extensions/revolution.extension.navigation.min.js",
"src/assets/js/extensions/revolution.extension.video.min.js",
"src/assets/js/dlmenu.js",
"src/assets/js/jquery.magnific-popup.js",
"src/assets/js/mixer.js",
"src/assets/js/jquery.easing.1.3.js",
"src/assets/js/owl.carousel.js",
"src/assets/js/slick.js",
"src/assets/js/jquery.appear.js",
"src/assets/js/theme.js"
]
I installed jQuery using below code.
npm install jquery --save
My component is like below
rev-slider.component.ts
import { Component, ElementRef, OnInit, AfterViewInit} from '#angular/core';
import * as $ from 'jquery';
#Component({
selector: 'app-rev-slider',
templateUrl: './rev-slider.component.html',
styleUrls: ['./rev-slider.component.css'
]
})
export class RevSliderComponent implements AfterViewInit {
constructor(private element: ElementRef) {}
ngAfterViewInit(): void {
($(this.element.nativeElement) as any).show().revolution({
//more text here
});
}
}
I added this component in parent component like below
<app-rev-slider></app-rev-slider>
I am getting below error in console.
ERROR TypeError: jquery__WEBPACK_IMPORTED_MODULE_0__(...).show().revolution is not a function
Try changing
import * as $ from 'jquery';
to
declare var $;

Angular: How to override the shared module service from different module

I have multiple modules say SchoolModule, UniversityModule, SharedModule
SharedModule has BaseService to which both SchoolModule and UniversityModule providers are extending
Now when I load my SchoolModule, I want BaseService should get the implementation of schoolService, and the same goes for UniversityModule
Structure
app
-- SharedModule
-- base.service
-- secret.service uses base.service
-- shared.component uses secret.service
-- SchoolModule
-- school.component uses shared.component
-- school.service
-- UniversityModule
-- university.component uses shared.component
-- university.service
StackBlitz
So how I can achieve this with Dependency Injection?
You have to declare your base service class as an abstract class with an abstract method getName()
export abstract class BaseService{
abstract getName(): string { return 'Base Service' }
}
export class SchoolService extends BaseService{
getName(): string { return 'School Service' }
}
Unfortunately, Angular2 can not inject a class from another module without get the import between modules, and if you need to lazy load it, things do not work.
There is a project that load dynamically a component from another module.
It is difficult to import this in to your project, but saves you to not code twice.
This project can be found here.
The problem is that SecretService provided is the one build with build in UniversityModule last imported module in App Module so if you want to have SecretService update with correctly BaseService you have to provide both BaseService and SecretService in university and school component something like this in school.component.ts:
import { SchoolService } from './school.service'
import { BaseService } from '../shared/base.service'
import { SecretService } from '../shared/secret.service'
#Component({
selector: 'app-school',
template: `SchoolName :: <app-shared></app-shared>`,
providers: [
{ provide: BaseService, useClass: SchoolService },
SecretService]
})
export class SchoolComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
and in university.component.ts
import {  UniversityService } from './university.service'
import { BaseService } from '../shared/base.service'
import { SecretService } from '../shared/secret.service'
#Component({
selector: 'app-university',
template: `UniversityName :: <app-shared></app-shared>`,
providers: [{ provide: BaseService, useClass: UniversityService },
SecretService]
})
export class UniversityComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
But why you wanna wrap base service in SecretService instead directly use BaseService in shared component ?
Using BaseService like this in shared.component.ts
import { Component, OnInit } from '#angular/core';
import { BaseService } from './base.service'
#Component({
selector: 'app-shared',
template: `{{name}}`
})
export class SharedComponent implements OnInit {
name: string
constructor(private ss: BaseService) {
this.name = ss.getName()
}
ngOnInit() {
}
}
Using BaseService you will solve this injection problem without any workaround on SecretService

Meterial Design javascript method from Angular 7 component

*Solved it by using: 'declare var md:any;' after imports *
I am building a website in which I am using 'creative tim template for dashboard'
I am using date and time picker, the issue I am facing is the DateTime picker is initialized only once and 'it worked when the component and loaded for the first time but when I switch components then DateTime picker stop working',
the solution that I've found out is I have to initialize DateTime picker every time component is loaded by using the initialize method in the component
but then I receive the error src/app/components/booktrip/booktrip.component.ts(24,5): error TS2304: Cannot find name 'md'.
here's my code
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup,FormControl, Validators } from '#angular/forms';
import { Trip } from '../../mockups/trip.mockup';
#Component({
selector: 'app-book-trip',
templateUrl: './book-trip.component.html',
styleUrls: ['./book-trip.component.css']
})
export class BookTripComponent implements OnInit {
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
md.initFormExtendedDatetimepickers();
}
bookTrip(trip) {
console.log(trip);
}
}
My angular.json is
"scripts": [
"src/assets/js/core/jquery.min.js",
"src/assets/js/core/popper.min.js",
"src/assets/js/core/bootstrap-material-design.min.js",
"src/assets/js/plugins/perfect-scrollbar.jquery.min.js",
"src/assets/js/plugins/moment.min.js",
"src/assets/js/plugins/sweetalert2.js",
"src/assets/js/plugins/jquery.validate.min.js",
"src/assets/js/plugins/jquery.bootstrap-wizard.js",
"src/assets/js/plugins/bootstrap-selectpicker.js",
"src/assets/js/plugins/bootstrap-datetimepicker.min.js",
"src/assets/js/plugins/jquery.dataTables.min.js",
"src/assets/js/plugins/bootstrap-tagsinput.js",
"src/assets/js/plugins/jasny-bootstrap.min.js",
"src/assets/js/plugins/fullcalendar.min.js",
"src/assets/js/plugins/jquery-jvectormap.js",
"src/assets/js/plugins/nouislider.min.js",
"src/assets/cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.js",
"src/assets/js/plugins/arrive.min.js",
"src/assets/buttons.github.io/buttons.js",
"src/assets/js/plugins/chartist.min.js",
"src/assets/js/plugins/bootstrap-notify.js",
"src/assets/js/material-dashboard.min40a0.js",
"src/assets/demo/demo.js",
"src/assets/demo/jquery.sharrre.js"
]
and the error i am getting is
Error
I am not able to generate production build.
I am stuck for too long.. is there any possible solution ??
I think it's only a TypeScript error, and that md is actually defined -it's just that TypeScript doesn't know about it-.
Have you tried importing it directly to the files where you use md?
import * as md from 'material-dashboard';
You can read more about it here: https://hackernoon.com/how-to-use-javascript-libraries-in-angular-2-apps-ff274ba601af
This is how I think your component should look like, in the end:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup,FormControl, Validators } from '#angular/forms';
import { Trip } from '../../mockups/trip.mockup';
import * as md from 'material-dashboard';
#Component({
selector: 'app-book-trip',
templateUrl: './book-trip.component.html',
styleUrls: ['./book-trip.component.css']
})
export class BookTripComponent implements OnInit {
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
md.initFormExtendedDatetimepickers();
}
bookTrip(trip) {
console.log(trip);
}
}

Application Insights does not track unhandled browser exceptions in Angular app

I'm experiencing an issue with the Microsoft Application Insights SDK for JavaScript that was closed/fixed awhile ago: https://github.com/Microsoft/ApplicationInsights-JS/issues/282
I created a brand new Angular app using the Angular CLI. Then I made these changes, following this article.
Added a monitoring service:
import {Injectable} from '#angular/core';
import {AppInsights} from 'applicationinsights-js';
#Injectable()
export class MonitoringService {
private config: Microsoft.ApplicationInsights.IConfig = {
instrumentationKey: 'KEY_GOES_HERE',
enableDebug: true,
verboseLogging: true
};
constructor() {
if (!AppInsights.config) {
AppInsights.downloadAndSetup(this.config);
}
}
logPageView(name?: string, url?: string, properties?: any, measurements?: any, duration?: number) {
AppInsights.trackPageView(name, url, properties, measurements, duration);
}
logEvent(name: string, properties?: any, measurements?: any) {
AppInsights.trackEvent(name, properties, measurements);
}
trackException(exception: Error) {
AppInsights.trackException(exception);
}
}
Added it to my app.component.ts:
import {Component, OnInit} from '#angular/core';
import {MonitoringService} from './monitoring.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MonitoringService]
})
export class AppComponent implements OnInit {
title = 'app works!';
constructor(private monitoringService: MonitoringService) { }
ngOnInit() {
this.monitoringService.logPageView();
}
throwAnException() {
this.monitoringService.trackException(new Error('manually track exception'));
throw 'this should appear in app insights'; // but it doesn't
}
}
Made a simple button for throwing the exception in my app.component.html:
<h1>
{{title}}
</h1>
<div (click)="throwAnException()">Click to throw an exception</div>
Logging a page view works, as does tracking the exception by explicitly calling trackException. From reading the documentation and various articles, I was under the impression that uncaught exceptions would always automatically get sent to Application Insights. However, I am not seeing any of those show up in the portal.
What could I be missing here?
Using these versions:
applicationinsights-js: 1.0.11
#types/applicationinsights-js: 1.0.4
I've struggles with the same thing and here is the things you need to know to hack it through:
What is happenning?
Angular catches all the exceptions (swallows them!) and just logs them inside console. I have not seen this behavior being explicitly told in any documentation, but I've tested this in code, so trust me. On the other hand only uncaught exceptions are autocollected! (see here). For collecting caught exceptions ( as is mostly the case when using angular framework) you have to call trackException() explicitly in your code.
How to solve it :
We will implement a service (called MonitoringService in code below) to communicate with azure application insights. Then we will tell angular to use this service to log exceptions in azure ai, instead of logging just into browser console, by extending ErrorHandler class.
1) implement MonitoringService:
We'll be using a service named MonitoringService to communicate with azure application insights. Implement that service like this:
import { Injectable } from "#angular/core";
import { ApplicationInsights } from "#microsoft/applicationinsights-web";
import { environment } from "#env/environment";
#Injectable({
providedIn: "root",
})
export class MonitoringService {
private appInsights: ApplicationInsights;
constructor() {}
startMonitoring(): void {
this.appInsights = new ApplicationInsights({
config: {
instrumentationKey: environment.appInsights.instrumentationKey,
},
});
this.appInsights.loadAppInsights();
this.appInsights.trackPageView();
}
logException(exception: Error, severityLevel?: number) {
this.appInsights.trackException({
exception: exception,
severityLevel: severityLevel,
});
}
}
startMonitoring() should be called on app start up.
2) start monitoring on app start up:
Angular projects mostly have a app.component.ts file which belongs to the root module and is bootstrapped/initialized as the first component. By the term "on app start up", I actually mean the time this component is being initialized.
We'll create an instance of MonitoringService and have it start its job:
import { Component } from '#angular/core';
import { MonitoringService } from 'services/monitoring.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(
private monitoringService: MonitoringService
) {
this.monitoringService.startMonitoring();
}
}
3) Log errors into application insights, before they are swallowed by framework:
Extend ErrorHandler class in your project. This class is actually a hook for centralized exception handling in angular spa. Use this hook, to log exceptions before they are swallowed by framework:
import { Injectable, ErrorHandler } from '#angular/core';
import { MonitoringService } from './monitoring.service';
#Injectable({
providedIn: 'root'
})
export class GlobalErrorHandlerService implements ErrorHandler {
constructor(private monitoringService: MonitoringService) { }
handleError(error: any): void {
console.error(error);
this.monitoringService.logException(error);
}
}
4) Register the ErrorHandler with Angular:
In the AppModule make sure to register this Handler with Angular:
#NgModule({
providers: [{provide: ErrorHandler, useClass: GlobalErrorHandlerService}]
})
class AppModule {}
I don't think AppInsights has any knowledge of Angular and the other way around, Angular doesn't know about app insights so you'll probably have to add this in by yourself using a custom ErrorHandler. Have a look at the ErrorHandler official documentation. If you put your this.monitoringService.trackException call in the handleError there it should work fine.

How to import js file in typescript?

I want to import js file in typescript.
And I want to access object and function in the js files.
Also I added js file in index.html but It doesn't working too.
so I find a clue that "import '[js file path]'" but it doesn't working.
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { NavParams } from 'ionic-angular';
import '../../pages/mobile.js';
#Component({
selector: 'page-success',
templateUrl: 'success.html'
})
export class SuccessPage {
constructor(public navCtrl: NavController, public navParms: NavParams) {
let centerPos = new atlan.maps.UTMK(953933.75, 1952050.75);
}
}
This is success.ts file. I want to find 'atlan' object.
Give me a solution please. Thx a lot!
You have to use the declare keyword so you do not get any compilation errors. You can do the following
import { Component } from '#angular/core';
....
/* Here you are telling typescript compiler to
ignore this variable it did not originate with typescript.*/
declare var atlan: any;
#Component({
selector: 'page-success',
templateUrl: 'success.html'
})
export class SuccessPage {
....
}
In your file ../../pages/mobile.js, you must export your atlan object (if you can edit this file of course), then, you import it the same way you do with everything.

Categories