在Angular 6服务中未定义HttpClient实例

时间:2018-07-20 22:56:15

标签: angular

我有一个包装HttpClient的服务。该服务由组件调用。问题是,当我在组件构造函数中注入服务时,它是undefined。此外,由于console.log不会显示任何内容,因此服务构造函数似乎根本不执行。有什么想法吗?

@Injectable({
  providedIn: 'root'
})
export class MyHttpService {

  constructor(public httpx: HttpClient) {
        console.log("in the constructor - " + this.httpx) // <-- this is never printed
  }

  call () {
        let reqData = { act: 'R'};
        this.httpx.post('/myurl', reqData).subscribe(result => {
            console.log(result);
          }, error => console.log('There was an error: '));
    }
}

相关模块定义如下:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient } from '@angular/common/http';
import { MyHttpService } from './http.service';

@NgModule({
  imports: [
    CommonModule,
    HttpClientModule, 
    HttpClient
  ],
  declarations: [
    MyHttpService
  ],
  exports: [
    MyHttpService
  ]
})
export class CoreServiceModule {}

调用服务的组件:

@Component({
      selector: 'some-selector',
      templateUrl: 'some-url.html'
    })
export class MyComponent implements OnInit{ 

    constructor(public http:MyHttpService){
          console.log(http);  // <-- this prints undefined
    }

    ngOnInit() {
        let x = this.http.call();  // <-- this fails as http is undefined       
    }


}

以及组件模块:

@NgModule({
  declarations: [MyComponent],
  exports: [MyComponent],
  imports: [BrowserModule, CoreServiceModule],
  bootstrap: [MyComponent]
})
export class MyModule {}

3 个答案:

答案 0 :(得分:2)

请注意,我是Angular的新手,但是最近我做了类似的事情,在查看自己的类似项目时,我发现了一些区别:

1。。注入httpClient时,它是私有而不是公共

constructor(private http: HttpClient) { }

2。。我认为您需要添加

import { HttpClient } from '@angular/common/http';

位于MyHttpService模块的顶部。

3。。请注意,您用相同的名称两次定义了相同的模块:

HttpClientModule, 
HttpClient

我会为了整洁而删除一个。

希望这会有所帮助。

更新-1:

这就是我测试应用程序中的内容。希望您会发现一些与众不同的地方,但这绝对对我有用。

app.module.ts:

…
import { HttpClientModule } from '@angular/common/http';
import { HttpService } from './http.service';
…
@NgModule({
  declarations: [
  …
],
imports: [
    …
    HttpClientModule,
    …
  ],
}],
providers: [HttpService],
bootstrap: [AppComponent]
})
export class AppModule { }

我为http客户端服务创建了一个单独的文件。

http.service.ts:

…
import { HttpClient } from '@angular/common/http';
…

@Injectable({
  providedIn: 'root'
})

export class HttpService {

  private _loginUrl = "http://...";

  …

  // inject http client in constructor. Make sure it is imported.

  constructor(private http: HttpService) { }

  // Sample function
  loginUser(user) {
    return this.http.post<any>(this._loginUrl, user);
  }
}

以及从我的观点/组成部分来看:

login.component.ts:

import { HttpService } from '../http.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  …
  constructor(private _http: HttpService) {
  }

  ngOnInit() {

  }

  loginUser() {
      this._http.loginUser(this.loginUserData).subscribe...
  }
}

答案 1 :(得分:1)

您应该尝试类似的操作,不要忘记从ModuleWithProviders导入@angular/core接口。

export class CoreServiceModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: CoreServiceModule,
      providers: [MyHttpService]
    }
  }
}

请注意,您需要在app.module.ts中导入此“共享模块”,并且在app.module中声明它时,必须调用forRoot()方法。 这样,您就可以在应用程序中的任何位置使用此单例,而无需再次冒任何风险。

答案 2 :(得分:0)

我遇到了类似的问题:

this.httpx is undefined

最令我惊讶的是,将服务中的函数更改为箭头函数解决了问题:

  call = () => {
        let reqData = { act: 'R'};
        this.httpx.post('/myurl', reqData).subscribe(result => {
            console.log(result);
          }, error => console.log('There was an error: '));
    }

任何时候 this 是未定义的,我首先检查的是“箭头”功能是否有帮助。比我感到舒服的次数更多,它确实如此。我必须假设这是古老的 javascript this-fiasco 所做的。