Angular5 httpClient get: невозможно прочитать свойство 'toLowerCase' из неопределенного

Я пытаюсь получить список пользователей из API, но получаю следующую ошибку:

TypeError: Cannot read property 'toLowerCase' of undefined
at HttpXsrfInterceptor.intercept (http.js:2482)
at HttpInterceptorHandler.handle (http.js:1796)
at HttpInterceptingHandler.handle (http.js:2547)
at MergeMapSubscriber.eval [as project] (http.js:1466)
at MergeMapSubscriber._tryNext (mergeMap.js:128)
at MergeMapSubscriber._next (mergeMap.js:118)
at MergeMapSubscriber.Subscriber.next (Subscriber.js:92)
at ScalarObservable._subscribe (ScalarObservable.js:51)
at ScalarObservable.Observable._trySubscribe (Observable.js:172)
at ScalarObservable.Observable.subscribe (Observable.js:160)

У меня есть компонент входа в систему, который вызывает homeService.getUsers(), который использует HttpClient для получения пользователей, но http-запрос никогда не достигает сервера.

login.component.ts:

import { Component, OnInit } from '@angular/core';

import { HomeService } from '../service/home.service';
import { User } from '../domain/user';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

  user: User = {
      id: undefined,
      userName: undefined,
      password: undefined
  }; 
  users: User[];

  constructor(
    private homeService: HomeService
  ) { }

  ngOnInit() {
    this.getUsers();
  }

  getUsers(): void {
    this.homeService.getUsers()
    .subscribe(users => this.users = users);
  }
}

Home.service:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';

import { User } from '../domain/user';
import { MessageService } from '../service/message.service';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable()
export class HomeService {

  private usersUrl: 'http://localhost:8080/users';

  constructor(
    private http: HttpClient,
    private messageService: MessageService
  ) { }

  getUsers (): Observable<User[]> {
    return this.http.get<User[]>(this.usersUrl)
      .pipe(
        tap(users => this.log(`fetched users`)),
        catchError(this.handleError('getUsers', []))
      );
  }

  /**
  * Handle Http operation that failed.
  * Let the app continue.
  * @param operation - name of the operation that failed
  * @param result - optional value to return as the observable result
  */
  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead

      // TODO: better job of transforming error for user consumption
      this.log(`${operation} failed: ${error.message}`);

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }

  private log(message: string) {
    this.messageService.add(message);
  }

}

и app.module:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { HttpClientXsrfModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { HomeService } from './service/home.service';
import { MessagesComponent } from './messages/messages.component';
import { MessageService } from './service/message.service';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    LoginComponent,
    RegisterComponent,
    MessagesComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    HttpClientXsrfModule.withOptions({
      cookieName: 'My-Xsrf-Cookie',
      headerName: 'My-Xsrf-Header',
    })
  ],
  providers: [HomeService, MessageService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Я вижу сообщение об ошибке, отображаемое в журнале, так что похоже на ошибку от HttpClient. Но я не могу понять, почему происходит сбой перед отправкой запроса Http на сервер.

3 ответа

У меня та же проблема. Проблема заключалась в том, что я объявил URL-адрес, но при выполнении httpget я понял, что URL-адрес не был назначен с каким-либо значением:

Возможный случай: Пример: private yourUrl: string;

и в вашем вызове http: верните this.http.get(this.yourUrl, {headers: this.headers})

Кажется, что вы объявили переменную неправильно, что делает ее неопределенной: попробуйте это

Для аккуратного кодирования

interface User = {
      id: number;
      userName: string;
      password: string;
  }

user: User;

Также исправьте эту строку из

private usersUrl: 'http://localhost:8080/users';

к

private usersUrl =  'http://localhost:8080/users';

Это, вероятно, где проблема

Проблема заключается в переданном вами URL:private usersUrl: http://localhost:8080/users'; .

Должно получиться так:private usersUrl: string='http://localhost:8080/users';

Я думаю, что ваше объявление URL не является правильным, попробуйте следующий способ:

private usersUrl = 'http://localhost:8080/users';

У меня такая же проблема. Как сказал @Canlla, необходимо было изменить видимость переменной url с публичной на приватную.

Странно, но что-то меняло свою ценность! Во всяком случае, это должно быть частным, так как нам не нужен доступ на тамплате.

Кроме того, в моем случае мне нужно было добавить NgIf / NgElse, чтобы избежать привязки данных до завершения загрузки:

<mat-list *ngIf="transactions | async; let transactions;else loading">
      <div *ngFor="let transaction of transactions">
        <h3 mat-subheader>{{ transaction.dueDate }}</h3>        
        <mat-list-item>
          <img matListAvatar src="https://source.unsplash.com/random/100x100" alt="...">
          <span matLine class="mat-body-2"> {{transaction.description}} </span>
          <p matLine class="col col-6 left-align">
            <span class="mat-body-1"> {{transaction.categoryName}} </span>
            <br>
            <span class="mat-caption"> {{transaction.accountName}} </span>
          </p>
          <p class="col col-6 right-align">
            <span class="mat-subheading">{{ transaction.amount | currency:'BRL':'symbol' }}</span>
          </p>
        </mat-list-item>       
      </div>
    </mat-list>

<ng-template #loading>Loading...</ng-template>

Так вот:<mat-list *ngIf="transactions | async; let transactions;else loading">

У меня есть *ngIf с async труба, чтобы показать mat-list если transactions загрузил. следующий let user оператор true, создавая локальную переменную шаблона, которой Angular присваивает значение из Observable.

Иначе else loading сообщает Angular, если условие не выполнено, чтобы показать шаблон загрузки.

Проверьте это превосходное сообщение от @coryrylan: https://coryrylan.com/blog/angular-async-data-binding-with-ng-if-and-ng-else

Я также столкнулся с подобной ошибкой, и, чтобы решить ее, я немного посмотрел и понял, что неправильно указал URL-адрес.

Объявление должно быть примерно таким

private urlVariable = 'http://sampleurl.com';
Другие вопросы по тегам