Angular 4 http调用执行两次

时间:2017-09-06 20:43:35

标签: angular express

我有一个快速服务器和Angular 4应用程序,它们在一个项目中共存。它基于这个启动器: https://github.com/vladotesanovic/angular2-express-starter

我遇到的问题是,当Angular发帖或获取时,它会发射两次。
enter image description here

您可以想象在发帖时这是一个什么问题!

这是我的组成部分:

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();
      }
}

服务是:

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);
}
}

app.module是:

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 { }

对于服务器端,我可以添加更多代码或将整个帖子发布到GitHub,但proxy.conf.json和package.json与他的启动器基本相同。我的猜测是模块正在加载或者我使用Observables错误了吗?

的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
  }
}

编辑以显示不同的方法。

即使我使用Promises执行此操作,我仍然遇到同样的问题,这让我觉得它仍然是路由器或app.module中的东西。

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));
    }

}

这是服务

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);
      }
  }

enter image description here

2 个答案:

答案 0 :(得分:0)

您在Chrome开发工具中看到两次调用触发的事实意味着问题出在客户端。

我的建议是订阅该调用,而不是将返回的observable分配给本地属性。 然后,您可以在调用服务的方法的入口点处创建一个断点。一旦命中,请查看调用堆栈以查看谁正在解雇呼叫。 我猜你会看到两次调用getSettings()的OnInit方法。 在这种情况下,我会假设您的组件由于某种原因在您的应用程序中被创建了两次。

答案 1 :(得分:0)

罪魁祸首原来是第三方: https://github.com/aitboudad/ngx-loading-bar

如果您使用的是ngx-loading-bar,则LoadingBarHttpModule将导致此行为。我还没有设法让LoadingBarHttpClientModule工作。