ErrorException:'Trying to get property of non-object' 从 Angular 5 服务向 Laravel 5.4 API 发送 POST 请求时

ErrorException: 'Trying to get property of non-object' while sending a POST request from Angular 5 Service to Laravel 5.4 API

我正在为我的 Angular 前端尝试从 Laravel API 访问数据。 要接收所需的数据,我必须将 'id' 作为 POST 发送到 url,后者又查询数据库,并将 returns 结果作为 JSON。 使用 POSTMAN 和其他 API 测试工具,我已经验证端点工作正常。 当我尝试从 Angular 发送 POST 请求时,我没有在 Laravel API 上收到 POST 数据,并出现以下错误。

请注意,我已经从代码中删除了实际的 URL

(1/1) ErrorException
Trying to get property of non-object

in ServiceRequestController.php line 209
at HandleExceptions->handleError(8, 'Trying to get property of non-object', '/home/removed_name/public_html/KoiKaam/app/Http/Controllers/ServiceRequestController.php', 209, array('request' => object(Request), 'serviceRequests' => object(Collection), 'id' => null, 'category' => null, 'cats' => object(Collection), 'cat' => null))
in ServiceRequestController.php line 209

虽然在 POSTMAN 和 Android 应用程序上测试的实际结果应该是 this (a screenshot of the result)

这是我用来获取结果的 angular 服务的代码

import { Http, Headers, RequestOptions } from '@angular/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { BuyDeliverRequests } from '../classes/buy-deliver-requests';


const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
const httpPostOptions = {
  headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
};

@Injectable()
export class BuyDeliverRequestsService {
    private url = 'http://removed_name/KoiKaam/public/api/serviceRequestByCategory'
  constructor(private http: HttpClient) { }


  getBuyDeliverServices(serverResponse: BuyDeliverRequests) {

      return this.http.post(this.url, {id: 1},  httpPostOptions).subscribe(
        data => { serverResponse = data.data; console.log(data); },
        err => console.log(err),
        () => console.log('Successful')
      );
  }
}

这是 URL/endpoint 去获取结果的函数:

 /*this function returns all rows of service request wrt category with their picture paths from service request pictures table
    and bids on that request request*/
    public function showServiceRequestbyCategory(Request $request)
    {
        $serviceRequests = new Collection();
        $id = $request->id; 

        $category = Category::find($id);
        $this->categories->push($category);
        $cats = $this->getChilds($id);
        try{
            foreach ($cats as $cat){
                $srv = $this->getServiceRequest($cat->id); //This is line 209 from the error
                foreach ($srv as $service){
                    $serviceRequests->push($service);
                }
            }

            $response["message"] = "Post Created Successfully";
            $response["error"] = false;
            $response["data"] = $serviceRequests;
            return json_encode($response);
        }
        catch (QueryException $e){
            $response["message"] = $e->errorInfo[2];
            $response["error"] = true;
            $response["sja"] = "2nd";
            return json_encode($response);
        }
    }

以下是在 Laravel

标识错误的行上调用的函数
private function getServiceRequest($category_id){
    try{
        $serviceRequest = ServiceRequest::where([['category_id','=', $category_id],
            ['in_process_flag', '=', false]])->paginate(5);
        if($serviceRequest){
            return $serviceRequest;
        }
    }
    catch(QueryException $e){

    }
}

找了很多,终于指出问题,找到了解决方法

问题

当Angular 5通过POST发送数据时,它发送为JSON。我在 Laravel 端的控制器期望作为 FORM 数据,可以作为 $request->id

访问

解决方案

有两种方法可以解决这个问题。在 Angular 侧或 Laravel 侧。

Laravel

其实很简单,不是直接访问$request我们首先需要将它存储在一个数组中

$data= $request->json()->all();

然后我们可以使用 $data 作为关联数组来获取所需的数据,例如如果我想使用 id,我会

$id= $data['id']; 然后根据需要使用 $id

Angular

我们首先需要序列化存储数据的对象,然后 POSTING 到 Laravel 后端。 jQuery 有它自己的函数 $.param() 但是因为我们使用 angular,我找到了一个自定义函数做同样的事情

formatData(data) {
let returnData = '';
let count = 0;
for (let i in data) {
  if (count == 0) {
    returnData += i + '=' + data[i];
  } else {
    returnData += '&' + i + '=' + data[i];
  }
  count = count + 1;
}
return returnData;
}

所以为了发送数据,我必须按如下方式编辑服务 class 功能

getServicesByCategory(category_id: number) {
let data = {id: category_id};
let body = this.formatData(data);
  return this.http.post(this.url, body,  httpPostOptions);
}

在另一个问题上找到这个函数 here