angular - Angular - ERROR 错误:尝试区分“[object Object]”时出错。只允许使用数组和可迭代对象
问题描述
我有一个 Angular7 前端和 Laravel 后端。我在 POSTMAN 上测试了端点,效果很好。但是,当我在 Serve 上进行测试时,它什么也没加载,我得到了这个错误。
我做了 log.console,我得到了这个错误:
ERROR 错误:尝试比较“[object Object]”时出错。只允许使用数组和可迭代对象
接口控制器:
public function indexSmsmt()
{
$smsmts = Smsmt::all();
return response()->json(['success' => true,'data'=>$smsmts], $this->successStatus);
}
public function showSmsmt($id)
{
$smsmt = Smsmt::find($id);
if (is_null($smsmt)) {
return $this->sendError('SMS Incoming not found.');
}
return response()->json(['success' => true,'data'=>$smsmt], $this->successStatus);
}
public function storeSmsmt(Request $request)
{
$smsmt = Smsmt::create($request->all());
return response()->json(['success' => $smsmt], $this-> successStatus);
}
public function editSmsmt($id)
{
$smsmt = Smsmt::find($id);
return response()->json(['success' => true,'data'=>$smsmt], $this->successStatus);
}
public function updateSmsmt(Request $request, $id)
{
$smsmt = Smsmt::find($id);
$smsmt = $smsmt->update($request->all());
return response()->json(['success' => true,'data'=>$smsmt], $this->successStatus);
}
public function deleteSmsmt($id)
{
$smsmt = Smsmt::find($id)->delete();
return response()->json(['success' => true], $this->successStatus);
}
环境.prod.ts
export const environment = {
production: true,
apiUrl: 'http://exampl.com/api',
};
smsmt.service.ts
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { catchError, tap, map } from 'rxjs/operators';
import { Smsmt } from '../models/smsmt';
import { environment } from 'src/environments/environment.prod';
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
@Injectable({
providedIn: 'root'
})
export class SmsmtService {
private API_URL= environment.apiUrl;
constructor(private http: HttpClient) { }
getSmsmts (): Observable<Smsmt[]> {
return this.http.get<Smsmt[]>(this.API_URL + '/indexSmsmt')
.pipe(
tap(smsmts => console.log('Fetch smsmts')),
catchError(this.handleError('getSmsmts', []))
);
}
getSmsmt(id: number): Observable<Smsmt> {
const url = this.API_URL + '/editSmsmt' + '/{id}';
return this.http.get<Smsmt>(url).pipe(
tap(_ => console.log(`fetched smsmt id=${id}`)),
catchError(this.handleError<Smsmt>(`getSmsmt id=${id}`))
);
}
addSmsmt (smsmt): Observable<Smsmt> {
return this.http.post<Smsmt>(this.API_URL + '/storeSmsmt', smsmt,
httpOptions).pipe(
tap((smsmt: Smsmt) => console.log(`added smsmt w/ id=${smsmt.id}`)),
catchError(this.handleError<Smsmt>('addSmsmt'))
);
}
updateSmsmt (id, smsmt): Observable<any> {
const url = this.API_URL + '/updateCSmsmt' + '/{id}';
return this.http.put(url, smsmt, httpOptions).pipe(
tap(_ => console.log(`updated smsmt id=${id}`)),
catchError(this.handleError<any>('updateSmsmt'))
);
}
deleteSmsmt (id): Observable<Smsmt> {
const url = this.API_URL + '/deleteSmsmt' + '/{id}';
return this.http.delete<Smsmt>(url, httpOptions).pipe(
tap(_ => console.log(`deleted smsmt id=${id}`)),
catchError(this.handleError<Smsmt>('deleteSmsmt'))
);
}
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
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
}
smsmt.component.ts
import { Component, OnInit } from '@angular/core';
import { SmsmtService } from '../../../services/smsmt.service';
import { Router } from '@angular/router';
import { Smsmt } from '../../../models/smsmt';
@Component({
selector: 'app-bulk-sms-outbox',
templateUrl: './bulk-sms-outbox.component.html',
styleUrls: ['./bulk-sms-outbox.component.scss']
})
export class BulkSmsOutboxComponent implements OnInit {
displayedColumns: string[] = ['msisdn', 'message', 'telco','error_message','error_code', 'package_id'];
data: Smsmt[] = [];
isLoadingResults = true;
constructor(private api: SmsmtService) { }
ngOnInit() {
this.api.getSmsmts()
.subscribe(res => {
this.data = res;
console.log(this.data);
this.isLoadingResults = false;
}, err => {
console.log(err);
this.isLoadingResults = false;
});
}
ngOnDestroy(): void {
document.body.className = '';
}
}
组件.html
<tr *ngFor="let datas of data| paginate: { itemsPerPage: 5, currentPage: p }; let i = index">
<td>{{i + 1}}</td>
<td>{{datas.msisdn}}</td>
<td>{{datas.short_code_called}}</td>
<td>{{datas.package_id}}</td>
<td>{{datas.error_message}}</td>
<td>{{datas.error_code}}</td>
</tr>
什么都没有被加载。
我该如何解决这个问题?
解决方案
在 Laravel 中获取数据时,你正在做
return response()->json(['success' => true,'data'=>$smsmts], $this->successStatus);
并返回一个对象,该对象具有该对象的数组 INSIDE,例如:
{
"sucess":"bla bla bla";
"data":[ ... ] <- Here
}
您要显示的数据在该变量中data
在文件smsmt.service.tsSmsmts[]
中,方法“getSmsmts()”接收一个( )数组this.http.get<Smsmt[]>
,但这不是您从后端发送的内容。
后端发送一个对象(里面有一个数组),但 http.get() 正在等待一个数组。这就是它抛出错误的原因。
您应该收到 http.get() 方法接收一个对象,如下所示:
getSmsmts (): Observable<any> { // Change here to any
return this.http.get<any>(this.API_URL + '/indexSmsmt') // and here too
.pipe(
tap(smsmts => console.log('Fetch smsmts')),
catchError(this.handleError('getSmsmts', []))
);
}
现在,在smsmts.component.ts文件中,试试这个:
ngOnInit() {
this.api.getSmsmts()
.subscribe(res => {
this.data = res.data; // change 'res' to 'res.data'
console.log(this.data);
this.isLoadingResults = false;
}, err => {
console.log(err);
this.isLoadingResults = false;
});
}
这可能有效。不习惯使用 .pipe 和 .taps,但它应该可以工作。请注意,这是一种解决方法,不建议接收和返回any
。你可以制作一个像“RequestResponse”这样的接口,它有两个属性:成功和数据,这样你就可以避免使用any
类型
推荐阅读
- video - 在多种模式下集成视频通话功能
- html - 使用 calc 时没有宽度和背景大小的响应式 css 网格 div
- javascript - javascript:检查复杂对象中是否存在大于给定值的值
- c# - .NET / C# Usb 通信库
- c# - ASP Net Core - 如何在多个级别上进行路由继承?
- ubuntu - 操作系统从 16.04 升级到 20.04 后,在戴尔笔记本电脑上未检测到网络摄像头
- uipath - Uipath-Studio,如何数据抓取产品列表?
- python - 使用 YAML 和过滤器登录 python
- matlab - 如何在 MATLAB 中为 ode15s 中的选项结构编写自定义“输出函数”以存储解向量的历史?
- javascript - 从字符串中删除某些重复出现的字符