0

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?

spinkus
  • 7,694
  • 4
  • 38
  • 62
  • How do you expect it to work? Http uses XHR, which is specific to browser. You could use Http from Angular Universal in theory, but why? – Estus Flask Nov 02 '16 at 13:07
  • Well, that is what I'm asking.. How to make it work. – spinkus Nov 02 '16 at 13:08
  • Please don't ask why I want to do it. Not really relevant. – spinkus Nov 02 '16 at 13:10
  • In fact, it is relevant, because it is most likely an XY problem. Http wasn't intended to be used like that. If you need to run existing A2 TypeScript app on server side, use Angular Universal, it may be troublesome but is quite straightforward. If you trying to do something from scratch in Node, it becomes be a PITA, because all Angular stuff - NgModule, DI, etc. - needs to be implemented also. You will end up writing typical A2 app, but in ES5/ES6 (you may take a look at [this answer](http://stackoverflow.com/a/39029435/3731501) to get some idea). – Estus Flask Nov 02 '16 at 13:35
  • OK, thanks. That is really going to the what of it though - semantics... The why in this *particular* case is that I was debugging and wanted to isolate `Http.get()` to ensure it behaved correctly in isolation and play with it etc. I foresee wanting to do this in other instances or possibly for other reasons depending on what is involved, which is why I didn't want to get hung up on the specific use case. – spinkus Nov 02 '16 at 18:50
  • I don't think that it will make any sense to do this in Node, because it will just be harder than doing that in browser and probably cause more problems due to Universal pre-prelease quality. With self-sufficient services it would be possible to use them with injector [like that](http://stackoverflow.com/a/38923612/3731501) but Http heavily relies on other core services and requires full-fledged app instance with NgModule and so on. – Estus Flask Nov 02 '16 at 19:10

1 Answers1

1

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..

spinkus
  • 7,694
  • 4
  • 38
  • 62