Поэтому я просто пытаюсь написать компонент и службу, которые из одного представления принимают вводимые пользователем данные и передают их API для проверки. Проблема в том, что в моем компоненте говорится, что служба по существу не имеет метода login и не определена. Однако я очень внимательно проверил и перепроверил, следуя документации Angular.io, но ничего не могу заставить работать.
LoginComponent.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from '../../../services/user.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
constructor(private userService: UserService) {
console.info('userService', userService);
}
ngOnInit() {}
handleSubmit(data) {
// https://api-test.sarahlawrence.edu:82/
this.userService.login(data)
.subscribe(user => console.info('user', user));
}
}
user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs/index';
import { catchError, map, tap } from 'rxjs/internal/operators';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
interface CredsInterface {
username: string;
password: string;
};
interface LoggedIn {
token: string;
}
@Injectable({
providedIn: 'root'
})
export class UserService {
private apiUrl = '<apiUrl>';
constructor(
private http: HttpClient
) { }
login (creds: CredsInterface): Observable<any> {
console.info('UserService.login()', creds);
return this.http.post<any>(`${this.apiUrl}/signin`, creds, {})
.pipe(
tap((loggedIn: LoggedIn) => {
console.info(`Login: ${loggedIn}`);
}),
catchError(this.handleError('login()', []))
);
}
/**
* 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
console.info(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
}
Я не понимаю, почему я получаю эту ошибку:
Итак, я вышел из службы, чтобы увидеть объект, и, как ни странно, метод помещается в прототип:
Я не понимаю, я что-то не так делаю?
@mwilson Я просто пошел и создал один, работающий над помещением туда всяких вещей: stackblitz.com/edit/angular-service-issues?file=src/app/…
Я думаю, вы забыли сохранить изменения. Он показывает кучу ошибок из-за отсутствующих модулей. Наверное, просто вопрос пути.
@mwilson Нет, потому что нет простого способа вытащить все файлы в стек блиц
Это могло быть частью проблемы. Код, который у вас есть, в основном является начальным кодом, поэтому может быть проще воссоздать простой пример в stackblitz, чтобы понять, в чем проблема. Глядя на это, похоже, что в настройке довольно много ошибок. Примечательно, что похоже, что вы ссылаетесь на компонент form-login, но ничего не найдено. В том же компоненте вы пытаетесь получить доступ к несуществующему свойству onHandleSubmit. Более чем вероятно, что происходит изменение префикса, и он пытается запустить эту директиву и не может ее найти, и поэтому вы получаете сообщение об ошибке.
Вот супер базовый пример использования сервиса angular и взаимодействия с ним через любой компонент. Я считаю, что это то, что вы пытаетесь сделать: stackblitz.com/edit/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Как вы называете этот метод handleSubmit?
Ошибка говорит о том, что он не может прочитать свойство login для undefined, что означает, что this.userService - это undefined. То, что метод login находится внутри прототипа, это нормально. Помните, что gets are deep and sets are shallow
Я думаю, что вы вызываете handleSubmit каким-то хитрым способом, который заставляет this ссылаться на другой объект, чем вы думаете.
Я только что видел stackblitz. Вы передаете ссылку на свою функцию с помощью [onHandleSubmit] = "handleSubmit", но когда она выполняется, this больше не является вашим компонентом LoginComponent.
Добавьте это в конструктор компонентов
this.handleSubmit = this.handleSubmit.bind(this)
Подробнее см. В этом посте: Функция обратного вызова Angular передает дочернему компоненту как @Input
Вы были правы, у меня в основном есть представление входа и форма входа, таким образом я могу повторно использовать форму входа в других местах. Добавление .bind(this) решило мою проблему! Большое спасибо, я привык реагировать там, где могу: onHandleSubmit = {() => { handleSubmit() }}, что позволяет использовать правильный объем, о котором вы говорите. Спасибо за помощь!!!!
У вас есть стекблиц?