S.Pinkus S.Pinkus - 16 days ago 5
Javascript Question

How to reuse Angular modules in node scripts

I want to reuse Angular2's

@angular/http
module from a node script. I'm using node v4.6.0,
@angular/http
version 2.1.2 from where
npm
gets it.

In this specific case I want to do this so I can easily isolate the module, confirm it's behavior, and play around with it (I mean I should be able to right - that is why it's called a module..). But I'm also after general advice on reusing Angular modules that don't have inherent browser dependencies in node.

Going off how the web application I'm looking at uses the module I tried this:

myUrl = '...'
http = require('@angular/http')
Http = new http.Http()
Http.get(myUrl).then(result => console.log(result))


And got:


TypeError: Cannot read property 'merge' of undefined
at mergeOptions (/home/sam/node_modules/@angular/http/bundles/http.umd.js:1578:30)
at Http.get (/home/sam/node_modules/@angular/http/bundles/http.umd.js:1672:45)
at repl:1:6
at REPLServer.defaultEval (repl.js:262:27)
at bound (domain.js:287:14)
at REPLServer.runBound [as eval] (domain.js:300:12)
at REPLServer. (repl.js:431:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
at REPLServer.Interface._onLine (readline.js:212:10)


So, is it done? Can it be done? How to go about it in the specific case of Http and in general?

Answer

After some (a lot) more learning about NG2 (Angular2), I realized what seems obvious once you learn it: That NgModules are not merely simple containers for stuff like the term "module" implies. They have very specific responsibilities and are tightly coupled to the NG2 core. So you can't just go about importing them into node. You need a bootstrapped NG2 core module to do just about anything with anything in NG2. Accessing Http which is an injectable service provided by the HttpModule is more complicated again, due to the injection system.

I was able to get somewhat isolated access to NG2's Http service using NG2's karma testing framework and utilities. The entire test setup is hideously complicated, but it's all done for you in the QuickStart application (the test setup essentially gives you a bootstrapped NgModule, in a server environment that you can run tests with). I stripped the quickstart app back and added a simple unit test like this to it then ran npm test:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DebugElement } from '@angular/core';
import { HttpModule, Headers, Http, Response } from '@angular/http';
import { Observable }     from 'rxjs';
import 'rxjs/add/operator/toPromise';

describe('Test frame for accessing Http!', function () {
  let http: Http

  beforeEach(async(() => {
   TestBed.configureTestingModule({
      imports: [ HttpModule ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
      http = TestBed.get(Http);
  });

  it('Test some HTTP', () => {
    http.get('/base/foo.json').toPromise()
      .then((r: Response) => console.warn(r))
      .catch((e: any) => console.warn('An error occured'))
  });
});

The server backing this is karma, so you may need to tweak it's configuration to tell it to serve whatever from where ever..

Comments