AJAX Send array as response from Laravel - php

I am trying to send from Laravel a response to an AJAX post request.
public function infoRoute(Request $request)
{
// Get info
$ship_id = $request->ship_id;
$startDate = $request->datepicker_start;
$endDate = $request->datepicker_end;
// Get all the locations between those dates
$routeArray = $this->measurementRepository->getCoordinates($ship_id, $startDate, $endDate);
$ship = $this->shipRepository->getShipForId($ship_id);
$info = $this->createRouteArrayForShip($ship, $routeArray);
if($request->ajax()) {
return response()->json(json_encode($info));
}
}
protected function createRouteArrayForShip($ship, $routeArray)
{
$info['type'] = "showRoute";
$index = 0;
foreach($routeArray as $coordinates)
{
$info['info']['route']['loc'. $index] = $coordinates;
$index++;
}
$info['info']['shipInfo'] = $ship;
//dd($info);
return $info;
}
When I receive the information and process it with jQuery, everything shows except from the route, that is empty.
Thank you,

The response()->json() method converts the given array into JSON using the json_encode() PHP function behind the scene.
Therefor you should remove your json_encode() from inside the response()->json() call.
Basically it should look like this
return response()->json($info);

Related

PHP/Laravel, url with multiples arguments

I'm building a Laravel app, and I need to use an URL that looks like that :
/api/ads?page=Actuel&formatsQuery[]=side&formatsQuery[]=leaderboard&deviceQuery=mobile
I have 3 parameters (page, formatsQuery (as an array), and deviceQuery).
Do you now how to hold his in routing and controller in order to have the correct value inside the controller's fonction?
I tried this :
routes/api.php
//request to get ads for given parameters
Route::get('/ads', [MediaController::class, 'findAds']);
and this (MediaController.php) :
public function findAds($page, $formatsQuery, $deviceQuery) {
echo $page;
if(sizeof($formatsQuery) <= 0 || sizeof($formatsQuery) > 3){
return $this->unvalidParametersError();
}
//transform format to position depending on deviceQuery
$position = [];
$res = [];
foreach ($formatsQuery as $format) {
$res = Media::where('position', $format)->inRandomOrder()->first()->union($res);
}
echo $res;
return $res;
}
then I test it with this :
public function test_findAds()
{
$ads = Ad::factory()
->has(Media::factory()->count(3), 'medias')
->count(3)->create();
$response = $this->get('/api/ads?page=Actuel&formatsQuery[]=side&formatsQuery[]=leaderboard&deviceQuery=mobile');
$response->assertStatus(200);
}
You are using a GET request to fetch your data. GET request is a type of request that you send parameters in URL using ? after URL and separating parameters with &. You can find out more about HTTP methods here.
In laravel using request parameters is so simple. First of all you need to add Request $request to your method prototype like this:
use Illuminate\Http\Request;
public function findAds(Request $request)
Then you can simply use $request->parameter to get the values. So you need to change your code like this:
public function findAds(Request $request){
$page = $request->page;
$formatsQuery = $request->formatsQuery;
$deviceQuery = $request->deviceQuery;
// Your code
}
And as #matiaslauriti mentioned in the comments you don't need to put [] after formatsQuery[] to send an array in GET request. Using the same key more than one time automatically makes an array for you.

Trying to get property 'staff 'of non-object when test REST API from Postman

I'm trying to understand the reason of this error message from postman when test API.
When I am testing my REST API from postman, it gives me error
ErrorException (E_NOTICE)
Trying to get property 'staff' of non-object
I try to find the problem but i can't find it. I kept searching for this but couldn't find an answer that will make this clear.
Anyone can help me on this?
Thanks!
This my code snippet
public function updatestatus($request, $leave, $is_api=0)
{
$status = $request->get('status');
$user = $is_api? JWTAuth::parseToken()->authenticate():Auth::user();
// $user = Auth::user();
$staff= $user->ref_user;
$applying_staff = $leave->staff;
$applying_user = $applying_staff->main_user;
//Approved
if($status==2 && $leave->status==1)
{
$leave->status =2;
$leave->approved_by_staff_id = $staff->staff_id;
$leave->approved_date = new Carbon('today');
$leave->save();
if($user->centre_id)
Helper::ClearObjective(10,$user->centre_id);
dispatch(new EmailJob($applying_user->email,new LeaveNotification(route('staff.leave.show',$leave->id), $leave->statusStr)))
->onConnection('database')
->onQueue('emails');
return response()->json(['Success'=>'Success']);
//send email
}
// Rejected
else if($status==3 && $leave->status==1)
{
$leave->status =3;
$leave->status_rejected_reason = $request->get('reason',null);
$leave->save();
if($user->centre_id)
Helper::ClearObjective(10,$user->centre_id);
$leave_cat = LeaveCategory::find($leave->leave_type);
if($leave_cat->leave_status!=0)
{
$leave_ent = $applying_staff->leaves()->where('leave_type',$leave->leave_type)->first();
if($leave_ent)
{
$leave_ent->leave_remaining += $leave->leave_days;
$leave_ent->save();
}
}
dispatch(new EmailJob($applying_user->email,new LeaveNotification(route('staff.leave.show',$leave->id), $leave->statusStr, $leave->status_rejected_reason)))
->onConnection('database')
->onQueue('emails');
//send email
}
//Cancelled
else if(($status==4 && $leave->status==2) || ($status==4 && $leave->staff_id == $staff->staff_id))
{
$leave->status =4;
$leave->status_rejected_reason = $request->get('reason',null);
$leave->save();
$leave_cat = LeaveCategory::find($leave->leave_type);
if($leave_cat->leave_status!=0)
{
$leave_ent = $applying_staff->leaves()->where('leave_type',$leave->leave_type)->first();
if($leave_ent)
{
$leave_ent->leave_remaining += $leave->leave_days;
$leave_ent->save();
}
}
dispatch(new EmailJob($applying_user->email,new LeaveNotification(route('staff.leave.show',$leave->id), $leave->statusStr,$leave->status_rejected_reason)))
->onConnection('database')
->onQueue('emails');
//send email
}
// return reponse()->toJson(compact('leave'));
return $leave;
}
Calling API
public function update(Request $request)
{
return $this->leaveApplicationRepository->updatestatus($request,1);
}
your updatestatus() need 3 parameter and your update() function pass only 2 paramenter;
public function update(Request $request)
{
// please provide you leave data
$leave = "your data is here";
return $this->leaveApplicationRepository->updatestatus($request,$leave, 1);
}
From the context that I can see, it is trying to reference the staff variable in:
$applying_staff = $leave->staff;
The non-object message will mean that $leave itself is the problem. Since you are passing in 1 to the call:
return $this->leaveApplicationRepository->updatestatus($request,1);
the 1 becomes the $leave parameter, and that is not an object, hence the error.
Maybe you think that by passing in 1, it will find the correct model automatically? This is not the case. You need to load that model explicitly.

Looping through multiple pages of a JSON request (Guzzle, Laravel, PHP)

New dev here so I am sorry if this is a simple question or something like that but haven't been able to find exactly what I am looking for (it totally could be that I am not asking the question correctly either) Basically I have a paginated list coming back from an api and I am not sure what the logic would be to be able to cycle through those pages. Here is the code that I have so far that works perfectly for the first page lol.
public function handle()
{
//This is the artisan command that runs on a timer and gets all the ticket and update fields that are needed and saves them to the database.
$tickets = $this->pullTicketSummary();
collect($tickets['data'])
->each(function ($currTicket) {
$ticketRow = Tickets::query()->firstOrCreate(['ticket_id' => $currTicket['id']]);
$ticketRow->status_id = $currTicket['status']['id'];
$ticketRow->category_id = $currTicket['category']['id'];
$ticketRow->user_id = $currTicket['assigned_to']['id'];
$ticketRow->jira_issue_id = $currTicket['jira_issue_id'];
$ticketRow->save();
collect($currTicket['updates'])->each(function ($update) use ($currTicket){
$updateRow = Update::query()->firstOrCreate(['update_id' => $update['update_id']]);
$updateRow->ticket_id = $currTicket['id'];
$updateRow->assignee_change = $update['assignee_change'];
});
});
Log::info('All tickets and updates were pulled successfully');
}
protected function pullTicketSummary()
{ //Function makes the guzzle request and returns the response from the happyfox api
$client = new Client();
$request = $client->get('https://happyfox.com/api/1.1/json/tickets/?size=50&page=1',
['auth' => ['N/A']);
$response = json_decode($request->getBody()->getContents(), true);
return $response;
}
With the fact that I am new if this is something that has been answered before that I missed please just shoot me over a link or if you are aware of any documentation that would help me get to the answer on my own that would be awesome! thanks!
Update your function to use the page number:
protected function pullTicketSummary($page)
{ //Function makes the guzzle request and returns the response from the happyfox api
$client = new Client();
$request = $client->get('https://happyfox.com/api/1.1/json/tickets/?size=50&page='.$page,
['auth' => ['N/A']);
$response = json_decode($request->getBody()->getContents(), true);
return $response;
}
//new function only to save the data from tickets variable. Necessary to reuse.
public function saveTicketsOrSomething($tickets)
{
collect($tickets['data'])
->each(function ($currTicket) {
$ticketRow = Tickets::query()->firstOrCreate(['ticket_id' => $currTicket['id']]);
$ticketRow->status_id = $currTicket['status']['id'];
$ticketRow->category_id = $currTicket['category']['id'];
$ticketRow->user_id = $currTicket['assigned_to']['id'];
$ticketRow->jira_issue_id = $currTicket['jira_issue_id'];
$ticketRow->save();
collect($currTicket['updates'])->each(function ($update) use ($currTicket){
$updateRow = Update::query()->firstOrCreate(['update_id' => $update['update_id']]);
$updateRow->ticket_id = $currTicket['id'];
$updateRow->assignee_change = $update['assignee_change'];
});
});
}
Then iterate until you finish all the pages:
$tickets = $this->pullTicketSummary(1); //first time
$numPages = $tickets['numPages']; //update here to get the actual value of number of pages
$this->saveTicketsOrSomething($tickets);
for ($i = 2; $i < $numPages; $i++) { //start on 2, cause we already have fetched page 1
$tickets = $this->pullTicketSummary($i); //other pages
$this->saveTicketsOrSomething($tickets);
}
Log::info('All tickets and updates were pulled successfully');

Parameters to a class constructor function

I'm trying to adapt a class of mine that handles tags for events stored in a JSON file. You can create tags, delete them, restore them, view them, etc. In the code below for this library you can see that I retrieve the array from the file during the constructor function so I use it and manipulate it throughout my classes' functions.
class tagHandler {
private $tagsFile = "/home/thomassm/public_html/functions/php/tags.json";
private $LstTags;
private $LstReturn;
function __construct() {
$this->LstTags = array();
if(!file_exists ($this->tagsFile)){
$fHND = fopen($this->tagsFile, "w");
$tmpArray = array(array("EID","EName","EColor", "EDel"));
fwrite($fHND, json_encode($tmpArray));
fclose($fHND);
}
$encodedInput = file ($this->tagsFile);
$this->LstTags = json_decode($encodedInput[0], true);
if(!$this->LstTags) $this->LstTags = array();
}
function __destruct(){
$this->update();
}
public function update(){
$this->LstTags = array_values($this->LstTags);
$fHND = fopen($this->tagsFile, "w");
fwrite($fHND, json_encode($this->LstTags));
fclose($fHND);
//empty memory region
$this->LstTags = array();
$encodedInput = file ($this->tagsFile);
$this->LstTags = json_decode($encodedInput[0], true);
}
//More functions that use the collected array here.
I am trying to adapt the class to deal with people signed up to my events. Each event has a record in my database that will store a field for an array of males who sign up and females who sign up. I wish for the constructor class to get the arrays(s) from the record so they can be manipulated like the previous class. The issue is to get the array I have to search the DB for a record with the Event ID (EID) and that will require a variable passed to the constructor function. To make things worse, this parameter has to be able to change in a loop. For example, the page listing all the events will have to use this class in a loop going through each record, so it can retrieve the array to manipulate it and then show it in a table / fullcalendar before repeating the process to get the next event. I have put the code I have so far below. Its not complete (some variables haven't been renamed to male and female, etc) and may be completely wrong, but it will give you a base to explain from.
class signupHandler {
private $LstMaleS;
private $LstFemaleS;
private $LstReturn;
function __construct($IntEID) {
$this->LstTags = array();
$StrQuery = "SELECT MaleS, FemaleS FROM tblEvents WHERE EID = ?";
if ($statement = TF_Core::$MySQLi->DB->prepare($StrQuery)) {
$statement->bind_param('s',$IntEID);
$statement->execute ();
$results = $statement->get_result ();
}
$this->LstTags = json_decode($encodedInput[0], true);
if(!$this->LstTags) $this->LstTags = array();
}
Thanks,
Tom
function decodeNames($StrNames){
$this->LstNames = array();
$this->LstNames = json_decode($StrNames, true);
if(!$this->LstNames) $this->LstNames = array();
$this->LstNames = array_values($this->LstNames);
}
function update(){
$this->LstNames = array_values($this->LstNames);
return json_encode($this->LstNames);
}
public function addSignUp($StrNames, $StrUsername, $StrStatus){
$this->decodeNames($StrNames);
$BlnPresent = false;
for($i = 0; $i < count($this->LstNames); $i++){
if($this->LstNames[$i][0] == $StrUsername){
$this->LstNames[$i][1] = $StrStatus;
$BlnPresent = true;
}
}
if($BlnPresent == false){
array_push($this->LstNames, array($StrUsername, $StrStatus, date("Y-m-d H:i:s")));
}
return $this->update();
}
I have decided to pass the encoded JSON array to the class each time I call a function from it. Before every function it is decoded and turned into an array and at the end it is then re-encoded and returned back to the file calling it. Now I no longer have any constructor or destruct functions.

Jquery json request and Kohana

I am trying to learn a little bit of jquery and more about the kohana framework. Ok so I wrote a simple test script to grab some entries from a database. The php works as in it returns the row in a json format, but I guess my jquery isn't working.
The json is suppose to return multiple rows so I want it to add all of those into the #chats div.
Here is my jquery code:
$(document).ready(function() {
$.getJSON('json/get_chat_entries/1',
function(data) {
$('#chats').append('<li>' + data.text + '</li>');
}
});
});
The get entries code is suppose to grab all the entries in the database matching the chat_id. Write now it seems to be only returning the first entry.
here is my get entries code:
function get_entries() {
$entries = $result = DB::select() - > from('chat_entries') - > where('chat_id', '=', $this - > chat_id) - > execute() - > current();
return $entries;
}
And this is the controller code:
public function action_get_chat_entries(){
$chat_id = $this->request->param('id');
$chat = new Model_Chat($chat_id);
echo json_encode($chat->get_entries());
}
Just remove ->current() from your get_entries() method.
Cleaned up a bit:
Model:
public function get_entries()
{
if (!$this->_loaded)
return array();
return DB::select()
->from('chat_entries')
->where('chat_id', '=', $this->chat_id)
->execute($this->_db);
}
Controller:
public function action_get_chat_entries()
{
$id = $this->request->param('id', FALSE);
$chat = new Model_Chat($id);
$this->request->headers['Content-Type'] = 'application/json';
$this->request->response = json_encode($chat->get_entries());
}
$results = DB::select(...)->from(...)->where(...)->execute();
echo json_encode(iterator_to_array($results));

Categories