Archive for March, 2017

March 4th, 2017
1:05 pm
Configuring Ionic 2 with Webstorm for development/debugging

Posted under Ionic
Tags ,

Having already configured Angular 2 with Webstorm  here, this post details the steps to get Ionic working in similar fashion, to be able to run and debug an ionic application running in a browser. The use of an android emulator/ a real android (and then IOS) will be dealt with later.

  1. First install Ionic 2 as detailed similarly either here or here.
  2. Next, configure Webstorm as detailed in this post here. Note that the first step adds a phonegap/cordova plugin which allows Ionic serve to be started within Webstorm, without using a separate command window. This trick is similar to step 10 in this post which does the same thing for angular 2/npm start. Note that I had to dig around for the phonegap/cordova executable – in my case it was a command/batch file located at C:/Users/SteveW/AppData/Roaming/npm/ionic.cmd , and note that Webstorm did require the .cmd extension explicitly to work. Per the instructions, ensure you select serve as the command and at this stage browser for the platform.
  3. The second step in the post configures a Javascript Debug configuration. Enter the name and the target URL. Note that in order to get breakpoints to be obeyed, I had to add an entry in the Remote URLs of local files section. In my case I just added the same url as at the top, against the top level project folder which was already shown. Prior to this, I could set a breakpoint successfully (meaning I did not have any sourcemap issues like the ones I hit with vs code here), but the breakpoint was not obeyed. Once I added the remote URL everything worked.

No Comments »

March 3rd, 2017
1:37 pm
Various DI related error categories in Angular 2

Posted under Angular
Tags ,

This post is a common point to document basic errors of the above kind.

1/ Karma tests fail to run giving the following kind of error:-

‘places-list’ is not a known element:
1. If ‘places-list’ is an Angular component, then verify that it is part of this module.
2. If ‘places-list’ is a Web Component then add “CUSTOM_ELEMENTS_SCHEMA” to the ‘@NgModule.schemas’ of this component to suppress this message. (”
<div> Places results:- </div>

[ERROR ->]<places-list></places-list>

In this case the application ran but the tests failed as above, following the addition of a new component, PlacesList, which was added via ng new component, and used in the root AppComponent.

This StackOverflow post details the issue and the solution. In my case the new component needed adding to the declarations list in TestBed.configureTestingModule in app.component.spec.ts as the component was a required dependency. I had added it (or ng generate may have, I cannot recall) to the @NgModule declarations list in app.module.ts, which enabled the application to run. However the test bed needed it too.

 

2/ I hit a similar issue with the PlacesService. I was getting this error on the tests:

Chrome 56.0.2924 (Windows 7 0.0.0) PlacesListComponent should create FAILED
Error: No provider for PlacesService!
Error: DI Error

I used 2 different ways around this problem.

a/ I added PlacesService as a provider in  places-list.component.spec.ts – this enabled both the tests and the app to work.

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [ PlacesListComponent ],
    providers: [PlacesService]
  })
  .compileComponents();
}));

b/ Alternatively, I could also add PlacesService as a provider in both app.component.ts (i.e. at the top level) and the test definition,  places-list-component.spec.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [PlacesService]
})
beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [ PlacesListComponent ],
    providers: [PlacesService]
  })
  .compileComponents();
}));

 

Whilst b/ defines the provider in 2 places, from basic knowledge this feels better as in a/ the provider is defined in the component that uses the service which feels almost as closely coupled as if I was not using DI at all.

Interestingly, when I removed the PlacesService as a provider from app.components.ts and added it to the @NgModule as a provider, in app.module.ts, this failed similarly. This was strange as I expected app.module.ts to declare the provider globally (expect perhaps for the testbeds).

This needs further looking into and understanding of the DI concepts – on the face of it, the providers (which are the actual lists of components to be injected) should be as decoupled as possible from the classes where they are used. At the moment, a lot of what I am seeing looks far too incestuous, coming from a background in Java/Spring where Spring is entirely external and responsible for the ‘provider list’.

No Comments »

March 3rd, 2017
10:23 am
Using <ng-container> as a dummy tag to simplify markup when directives are used

Posted under Angular
Tags ,

Sometimes you need an element to hang e.g. an *ngIf directive on, but you don’t want the element to appear in the markup.

In the following example, we end up with an extra unwanted <div> level just because we needed to hang the *ngIf somewhere (noting that it is not permissible to have the *ngIf on the same element as the *ngFor).

<div *ngFor="let place of places.rows">
  <div *ngIf="place.doc.type == 'place'">
    <span>{{place.doc.name}}, </span>
    <span>{{place.doc.strapline}}</span>
  </div>
</div>

Instead of a <div> we can use <ng-container>. This does not appear as an element in the markup (but does appear as a comment only) :-

<div *ngFor="let place of places.rows">
  <ng-container *ngIf="place.doc.type == 'place'">
    <span>{{place.doc.name}}, </span>
    <span>{{place.doc.strapline}}</span>
  </ng-container>
</div>

This is analagous to the <th:block> dummy element in Thymeleaf, which does exactly the same thing.

This StackOverflow post details this issue. This alternative post mentions the use of ng-if-start and ng-if-end, but notes that these are undocumented in Angular 2 so may not be fully supported.

For a related issue where nested loops are in use causing a similar problem, this post details the use of ng-repeat-start and ng-repeat-end as an alternative solution.

Note however that ng-repeat-start/ng-repeat-end only works for Angular 1.

No Comments »

March 1st, 2017
1:31 pm
Configuring Angular 2 with Webstorm for development/debugging

Posted under Angular
Tags

In contrast with the pain of all my previous attempts at getting debugging working using Angular 2 eclipse, webclipse, and vs code, this was thankfully almost a non event!

It has confirmed Webstorm as my preferred IDE going forward.

The aim of this exercise was simply to be able to debug an application generated using angular-cli – i.e. to put a breakpoint on the initial generated code and have it obeyed.

I went through the following steps:-

  1. Installed Node, npm and angular-cli as detailed on the angular2 quickstart page
  2. Downloaded and installed the current version of Webstorm (as a trial) from here
  3. Visited this page re setting up angular-cli for Webstorm and made sure all the actions were/had been done
  4. Opened an existing angular-cli generated project.
  5. Visited this jetbrains blog post re setting up for debugging.
  6. The above blog post points out that in the early access preview version of Webstorm 2017.1, no additional configuration was needed other than adding a run configuration using Run – Edit configurations… – Add – JavaScript Debug and entering the url (http://localhost:4200/). This was such a contrast with the previous pain of trying to get vs code working that I could not resist giving the EAP a try, so installed this version (which is available for download here, and is allowed as part of trial use).
  7. Note that Webstorm is Java based (a fork of IntelliJ) so needs a JVM. The 2016.3 release which I initially tried installed its own Java 8 by default. However, for the EAP I had to tick the box on the initial wizard screen to install java, or else it used whatever jre was available globally. As I use various versions, I run Webstorm with its own jre.
  8. Debugging worked exactly as stated. Initially, Webstorm complained that it needed its own debug plugin for chrome, and helpfully provided the relevant link to the chrome store in the message. I was able to install the plugin directly, and Webstorm then immediately started working with no further ado.
  9. To commence debugging it is necessary to start the application. This can be done outside Webstorm in a command window by entering npm start or ng serve.
  10. You can also set up a run configuration to allow starting within webstorm. To do this visit run/Edit Configurations. Press + to add a new configuration and select npm. Give the configuration a suitable name and ensure that the package.json field points to your package.json file for the project. Pick start for the desired command. The Node interpreter for the project should be already set up from the initial node/Webstorm installation – in my case this was E:\Program Files\nodejs\node.exe. Having done this you can run with this configuration and the project will build if required and start.
  11. Note that when using vs code, it was necessary to start chrome with its debug mode/debug port enabled, which required a shutdown of all chrome instances and starting using specific command line flags as detailed in my previous post here. This was a nuisance to have to do each time. However, with Webstorm, none of this is needed. To contrast the two approaches, vs code uses a vs code chrome plugin which talks to chrome using chrome’s standard debugging mechanism/debug port. However, for Webstorm, no plugin is needed at the Webstorm end, but it is using its own custom chrome plugin in chrome for debugging. This does not need any special startup for chrome – it just works.
  12. When talking to CouchDB, I hit CORS issues and initially installed a Chrome CORS plugin to get around this. Later I just enabled CORS in CouchDB which is simpler and more convenient, as detailed here.

Following this I was able to plant a breakpoint, modify a couple of assigned properties in the code, and continue execution, with the results of the changed assignments visible in the browser.

As an additional bonus, I tried the existing Tour of Heroes tutorial (which uses systemjs rather than webpack) under debug, and this also worked perfectly.

No Comments »

March 1st, 2017
12:05 pm
Angular 2– Issues debugging default angular-cli/webpack generated application

Posted under Angular
Tags , , ,

Further to getting the Tour of Heroes tutorial (which is systemjs based) debugging correctly in vs code (see here), I moved on to creating a new app via angular-cli as a basis for moving forward.

The point about angular-cli is that it uses webpack as its packaging tool, which is better than existing packagers for breaking down enterprise level applications. It mandates a standard for project file structure which was lacking in the past in angular, and creates everything according to that standard. It also allows additions of components etc. which will also conform to the same structure.

Previously I had settled on using vs code, as I had issues with all the previous IDEs I had tried (eclipse with angular 2 eclipse, webclipse) as per here).

I tried the following steps:-

  1. create a new angular project via ng new
  2. build/start it via npm start
  3. run chrome in debug mode via the following shortcut "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" –remote-debugging-port=9222
  4. debug in vs code using a suitable (clearly not as in the end I could not get it to work) launch configuration

The problem is that vs code could not map the .ts source to the .js. via the sourcemap, which is provided to do the mapping.
When adding a breakpoint, the following error occurs:-
“Breakpoint ignored because generated code not found”.

As vs code is widely used, there were a number of posts about this issue as follows :-

https://github.com/angular/angular-cli/issues/2453
https://github.com/angular/angular-cli/issues/1223
https://github.com/angular/angular-cli/issues/4526
https://github.com/angular/angular-cli/issues/2491

Unfortunately I could not resolve the problem via any of these.

A key point that these posts do not clarify on is that when starting with npm start or ng serve, any generated js file bundles (e.g. main.bundle.js) which are bundled js files under <project>/dist/) are deleted along with the <project>/dist directory, and the generated js is entirely served from memory. The IDE therefore has to get this js via a url, so all the discussion about tweaking the sourceMapPathOverrides to things like:-

"webpack:///*": "/*"
"webpack:///C:*":"C:/*" (for windows – substitute correct drive letter is the theory)

…seem to miss the point if they are aiming at target directories for the js. Of course, they may refer to the need to derive map keys for the sourcemap which would make sense if the sourcemap contains urls as values to return the generated js, but this is not made clear.
Either way, I could not get any of this to work in vs code and could not get a working breakpoint on the initial line of code that assigns the "app works" string.

In the end I dumped using vs code and gave Webstorm a try. This was immediately successful with almost no configuration needed – details as per this post.

No Comments »