I have a express server and Angular 4 application that cohabitate in one project. It is based upon this starter: https://github.com/vladotesanovic/angular2-express-starter
The issue I am having is that when Angular does a post or get, it fires twice.
You can imagine how this is an issue when doing a post!
This is my component:
import { Component, OnInit } from '@angular/core';
import { Settings } from '../shared/settings/settings';
import { SettingsService } from '../shared/settings/settings.service';
import { Observable } from 'rxjs/Observable';
@Component({
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.scss']
})
export class WelcomeComponent implements OnInit {
settings: Observable<Settings[]>;
error: any;
constructor(
private settingsService: SettingsService) {
}
ngOnInit() {
this.getSettings();
}
getSettings() {
this.settings = this.settingsService.getSettings();
}
}
The service is:
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import 'rxjs/add/operator/catch';
import { Settings } from './settings';
import {Observable} from 'rxjs/Rx';
import { ErrorComponent } from '../error/error.component';
import { MdDialog, MD_DIALOG_DATA } from '@angular/material';
@Injectable()
export class SettingsService {
constructor(private http: Http, private dialog: MdDialog) { }
extractData(res: Response) {
return res.json();
}
getSettings(): Observable<Settings[]> {
return this.http.get('/api/getSettings').map(this.extractData).catch(error => this.handleError(error));
}
private handleError(error: any): Promise<any> {
const dialog = this.dialog.open(ErrorComponent, {
data: {
error: error
}
});
return Promise.reject(error.message || error);
}
}
The app.module is:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { MaterialModule } from '@angular/material';
import 'hammerjs';
import { AppRoutingModule } from './app-routing.module';
import { FlexLayoutModule } from '@angular/flex-layout';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SettingsService } from './shared/settings/settings.service';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { OrderComponent } from './order/order.component';
import { ErrorComponent } from './shared/error/error.component';
import { SuccessComponent } from './shared/success/success.component';
import { TextMaskModule } from 'angular2-text-mask';
import { LoadingBarHttpModule } from '@ngx-loading-bar/http'; //https://github.com/aitboudad/ngx-loading-bar
import {enableProdMode} from '@angular/core';
@NgModule({
declarations: [
AppComponent,
WelcomeComponent,
OrderComponent,
ErrorComponent,
SuccessComponent
],
imports: [
BrowserModule,
HttpModule,
MaterialModule,
AppRoutingModule,
FlexLayoutModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
TextMaskModule,
LoadingBarHttpModule
],
providers: [
SettingsService
],
bootstrap: [
AppComponent
],
entryComponents: [
ErrorComponent,
SuccessComponent
]
})
export class AppModule { }
For the server side, I can add more code or post the entirety to GitHub, but the proxy.conf.json and package.json are essentially the same as his starter. My guess is that a module is being double loaded or perhaps I am using Observables wrong?
package.json:
"scripts": {
"start": "concurrently --kill-others \"npm run _server:run\" \"ng serve --aot=false --progress=false --proxy-config proxy.conf.json\"",
"lint:client": "ng lint",
"lint:server": "tslint './server/**/*.ts' -c ./server/tslint.json --fix",
"test:client": "ng test",
"e2e:client": "ng e2e",
"build": "ng build --prod --sm=false --aot --output-path=dist/client && npm run _server:build",
"_server:run": "tsc -p ./server && concurrently \"tsc -w -p ./server\" \"nodemon --delay 5 dist/server/bin/www.js\" ",
"_server:build": "tsc -p ./server",
"postinstall": "npm run build"
},
proxy.json.conf:
{
"/api": {
"target": "http://localhost:4300",
"secure": false
}
}
Edit to show a different approach.
Even if I do this with Promises, I still have the same issue, which makes me think it is something in the router or app.module still.
export class WelcomeComponent implements OnInit {
settings: Settings[];
error: any;
constructor(
public dialog: MdDialog,
private router: Router,
private settingsService: SettingsService) {
console.log('calling constructor');
}
async ngOnInit(): Promise<void> {
console.log('calling onInit');
this.getSettings();
}
async getSettings(): Promise<void> {
this.settingsService.getSettings()
.then(result => this.settings = result)
.catch(error => this.handleError(error));
}
}
Here is the service
async getSettings(): Promise<Settings[]> {
console.log('calling SettingsService');
try {
const response = await this.http
.get('/api/getSettings')
.toPromise();
return response.json() as Settings[];
} catch (error) {
await this.handleError(error);
}
}