Javascriptservices: Cant add third party plugin

Created on 10 Sep 2016  路  2Comments  路  Source: aspnet/JavaScriptServices

I am trying to add goofle maps to angular2 template. I restored package google-maps-api from npm. Add it to webpack.config.vendor.js to entry -> vendor. Then run webpack --config webpack.config.vendor.js and webpack. Then tried to use global variable GoogleMapsLoader in component but always getting that it does not exist. What am i doing wrong? Thanks for any help.

Update.
I could acieve adding new library. I am doing like this in my component:
import * as $ from 'jquery';
import * as GoogleMapsLoader from 'google-maps';
After this i can access this frameworks.

But after restart server, server-boot gives exception that google-maps is only for browser. Is there any better way to use external libraries, so it does not break server-boot?

Most helpful comment

But after restart server, server-boot gives exception that google-maps is only for browser. Is there any better way to use external libraries, so it does not break server-boot?

You just need your code to vary what gets executed according to whether it's on the server or not. One way is:

import * as ngUniversal from 'angular2-universal';

if (ngUniversal.isBrowser) {
    ...
} else if (ngUniversal.isNode) {
    ...
}

Or another way that's more idiomatically Angular 2-ish (and works better if you need to vary which libraries are actually loaded) is to use its DI system. For example, declare some interface representing the Google Maps library, e.g. in some file you import wherever it's needed:

export interface MappingSystem {
    doSomeMapsThing(): void;
}

use its DI system to register different implementations of MappingSystem when it's running on the server vs on the client. For example, in boot-client.ts you could have:

import * as ngCore from '@angular/core';
import { RealMappingSystem } from 'somelibrary';

... then in the array of providers passed to bootstrap, add:

ngCore.provide('myMappingSystem', { useValue: new RealMappingSystem() })

Whereas in boot-server.ts you'd have:

import * as ngCore from '@angular/core';
import { FakeMappingSystem } from 'someotherlibrary';

... and:

ngCore.provide('myMappingSystem', { useValue: new FakeMappingSystem() })

Finally, in any component that wants to receive a MappingSystem,

import * as ngCore from '@angular/core';

export class FetchData {
    public forecasts: WeatherForecast[];

    constructor(@ngCore.Inject('myMappingSystem') mappingSystem: MappingSystem) {
    }
}

All 2 comments

But after restart server, server-boot gives exception that google-maps is only for browser. Is there any better way to use external libraries, so it does not break server-boot?

You just need your code to vary what gets executed according to whether it's on the server or not. One way is:

import * as ngUniversal from 'angular2-universal';

if (ngUniversal.isBrowser) {
    ...
} else if (ngUniversal.isNode) {
    ...
}

Or another way that's more idiomatically Angular 2-ish (and works better if you need to vary which libraries are actually loaded) is to use its DI system. For example, declare some interface representing the Google Maps library, e.g. in some file you import wherever it's needed:

export interface MappingSystem {
    doSomeMapsThing(): void;
}

use its DI system to register different implementations of MappingSystem when it's running on the server vs on the client. For example, in boot-client.ts you could have:

import * as ngCore from '@angular/core';
import { RealMappingSystem } from 'somelibrary';

... then in the array of providers passed to bootstrap, add:

ngCore.provide('myMappingSystem', { useValue: new RealMappingSystem() })

Whereas in boot-server.ts you'd have:

import * as ngCore from '@angular/core';
import { FakeMappingSystem } from 'someotherlibrary';

... and:

ngCore.provide('myMappingSystem', { useValue: new FakeMappingSystem() })

Finally, in any component that wants to receive a MappingSystem,

import * as ngCore from '@angular/core';

export class FetchData {
    public forecasts: WeatherForecast[];

    constructor(@ngCore.Inject('myMappingSystem') mappingSystem: MappingSystem) {
    }
}

Thanks a lot for such great answer.

Was this page helpful?
0 / 5 - 0 ratings