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?
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.
Most helpful comment
You just need your code to vary what gets executed according to whether it's on the server or not. One way is:
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:
use its DI system to register different implementations of
MappingSystemwhen it's running on the server vs on the client. For example, inboot-client.tsyou could have:... then in the array of providers passed to
bootstrap, add:Whereas in
boot-server.tsyou'd have:... and:
Finally, in any component that wants to receive a
MappingSystem,