I am new to Laravel and am building a small project as my schooling. I have struck the above error and I cannot seem to fix it. Any help is appreciated.
In my controller I make the following call when first loading the page. The getDetails method works perfectly on page load, but fails with above error when I call it with Ajax as the user interacts with the page after load.
On page load the method is called and passed to it resulting values from earlier other method calls ($CSpec[0]->id and $CSize[0]->size_mm, which I can see as values 1 and 0.5) as follows:
$CD = CS::getDetails($CSpec[0]->id, $CSize[0]->size_mm);
Also in the controller I have the following function which triggered via a route used in an Ajax call:
public function itemDetails($ct, $cs)
{
return CS::getDetails($ct, $s);
}
The getDetails method looks like this:
public static function getDetails($ct, $cs)
{
return DB::table('recommend_view')
->where('recommend_view.id', '=', $ct)
->where('recommend_view.size_mm', '=', $cs)
->first();
}
I have this route:
Route::get('vd/cd/{cd}/{cs}',
['uses' => 'Application\VDController#itemDetails', 'as' => 'application.vdcdetails']);
When I use Ajax to call the same method it fails with the above error. The Ajax code produces the following url in the $.getJSON call:
http://my.app/vd/cd/1/0.5
If I dd() inside getDetails for each variable I can see the correct values passed to the method from the url / controller.
If I execute the query in MySQL Workbench, it works as expected:
select *
from `recommender_view`
where `recommender_view`.`ct_id` = 1
and `recommender_view`.`cs_size_mm` = 0.50
limit 1;
So the method works perfectly when called on initial page load with variables fed to it directly from other method calls, but when the variables are passed via the URL / Ajax it fails and I cannot seem to understand what the difference is.
UnexpectedValueException in Response.php line 403:
The Response content must be a string or object implementing __toString(), "object" given.
I believe I know what your issue is, however, please feel free to correct me.
What you're using is the Laravel query builder, which returns a stdClass object type in PHP, assuming it finds a result set for your query. This is effectively a "dumb" object that has no methods to "echo" or return. You can't cast to array, nor json etc.
So when the Laravel response object is trying to handle it, it can't use the __toString() method to deconstruct an appropriate response.
What you'd be better off doing is calling the query against a Model that extends the Illuminate Eloquent Model class.
In this instance, it COULD be something like this
CableRecommenderView::where('recommend_view.id', $ct)
->where('recommend_view.size_mm', $cs)
->first();
Eloquent is able to respond accordingly when being passed to the response object.
As an FYI, when using equals ('=') as the comparison operator in queries Eloquent (and possibly the query builder, although you'd have to check on that), you can forego explicitly defining it in the ->where() clause and simply pass the comparison variable as the second argument.
Hope that helps!
The ajax call expects a response to be passed back to it. It is unable to recognize the object you are trying to pass to it.
Look into creating responses http://laravel.com/docs/5.1/responses.
If you return a json response e.g
public function itemDetails($ct, $cs)
{
$item = CS::getDetails($ct, $s);
return response()->json(['data' => $item]);
}
The ajax call should work. Then you can retrieve from the data variable from your ajax.
Related
This is my code of route for getting data from Laravel backend.
Route::get('/get/card',[CardController::class,'getCardList'])->name('card.list');
I call it like below,
http://127.0.0.1:8000/get/card
Controller code
public function getCardList()
{
//code goes here
}
The above code is working fine. I'm trying to add a parameter for adding filtration as follows;
Route::get('/get/card{treeItemID?}',[CardController::class,'getCardList'])->name('card.list');
public function getCardList($treeItemID)
{
}
http://127.0.0.1:8000/get/card?treeItemID=1
But, I'm getting the error "Too few arguments to function app\Http\Controllers\CardController::getCardList()..."
Can anyone notice what's wrong with my code that gives the above error when the parameter is added? Any help would be highly appreciated.
if you want to get data like below url, please replace your route and method like below and check again.
http://127.0.0.1:8000/get/card?treeItemID=1
Route::get('/get/card',[CardController::class,'getCardList'])->name('card.list');
public function getCardList(Request $request){
$treeItemID = $request->input('treeItemID');
return $treeItemID;
}
You can use get and post both type of request for filtering purpose.
Scenario 1 => If you want to hide some parameter inside request then you can use POST type of request where use can pass data in form data and get from request inside in controller.
Route::post('/get/card',[CardController::class,'getCardList'])->name('card.list');
public function getCardList(Request $request){
$treeItemID = $request->treeItemID;
return $treeItemID;
}
Scenario 2 => If you do want to hide some parameter inside the request then you can use GET type of request where use can pass data in url and get from request or get from parameter url inside in controller.
Route::get('/get/card/{treeItemID}',[CardController::class,'getCardList'])->name('card.list');
public function getCardList($treeItemID){
$treeItemID = $treeItemID;
return $treeItemID;
}
EDIT:
I outputted the array and #apokryfos had mentioned something about resources not being able to be serialized.
Here is how some debug output looks: (Removed some information that is more sensitive)
Stream in Timestamp
It is my timestamp causing the issue. If I do
unset($user["timestamp"]);
Then almost everyone's solution works. So, the real reason was the resources was in there for my timestamp. How do I stop or fix that? I tried to do
public $timestamps = false;
This did not have any changes.
I have read through the documentation and a few tutorials. Sadly, I can't seem to find any documentation on what is returned and what functions are available for use when using Eloquent. Maybe I am just missing it.
However, I am using this code in my controller.
public function find($userName){
$user = UserSecurity::where('userName', $userName)->get();
//dd($user);
return Response()->json(['data' => $user], 200);
}
This is my router code.
$router->get('/UserSecurity/find/{userName}', ['uses'=>'UserSecurityController#find']);
I know that it is pulling the correct data from the database as if I uncomment the dd($user) I can see it on screen. However, if I try to send a response through Response()->json(..) it fails with this screen.
Image of Exception
I know I am probably using Response() incorrectly, but I have actually tried a number of different ways. Some just show empty responses and some crash similarly.
I have tried removing get() which from what I have found just returns nothing as there are no results. I have tried Response($user) and it was empty. I have tried return Response()->json($user); with the same type unsupported error.
Thanks for any help.
EDIT:
Changing a few code for testing. I changed to this
public function find($userName){
$user = UserSecurity::where('userName', $userName)->get()->toJson();
$user = json_encode($user);
return Response($user);
}
This returns false . I am not sure where the boolean is coming from. The original dd($user) actually has the correct information from the DB, so I know it is doing the query correct.
I think you must add the following in the top of your controller
then this code will help you.
use Illuminate\Support\Facades\Response;
The error message Type is not supported is actually coming from PHP's JSON serializer. There are only a very few types that PHP cannot serialise and the one that seems to be causing the issue in your particular case is a stream resource.
In order to check what is actually serialized in your model you will need to call:
$user = UserSecurity::where('userName', $userName)->get();
$user->map->jsonSerialize()->dd();
jsonSerialize exists because all Laravel models implement the JsonSerializable interface.
This will dump a collection of arrays of what PHP will attempt to serialise as JSON. The contents of this array are recursively serialised.
The default implementation of JsonSerializable in Model will attempt to serialize all model attributes but first will attempt to cast and call all accessors on attributes. This may or may not cause issues. At any rate the solution here is to figure out why there's a resource being returned in the jsonSerialize method and figure out the best way to hide it. Normally you can hide attributes by using
protected $hidden = [ 'timestamp' ];
however from your question it seems that the answer may not be so straight forward so may need to dig deeper.
I think you must add the following in the top of your controller:
use Illuminate\Support\Facades\Response;
and the controller must be like:
public function find($userName){
$user = UserSecurity::where('userName', $userName)->get();
return Response::json($user, 200);
}
PLease try like this
return response()->json(['status' => true, 'data' => $user],200);
I am already using this in my code
Using where('...')->get() returns a collection which cannot be used in response()->json().
Try using:
public function find($userName){
$user = UserSecurity::where('userName', $userName)->first();
return response()->json(['data' => $user->toArray()], 200);
}
here is just a typo error, you must write response() in lowercase instead or Response() because Response is a class, while response() is a magic Laravel function which already instantiates the class Response, and that you can use to return a Response instance.
I am trying to create a generic method that will be able to save all data from different models depending on which "entity" I am handling in the code. As you can see below, I have a variable $entity on which I want decide loading a model and then after that calling a method from it.
The two commented lines in my example are showing what I am trying to achieve, but they are not working. The uncommented (non-dynamic) line $this->companylocation_model->save(...) is working fine.
The commented experiment gives this error: call_user_func() expects parameter 1 to be a valid callback, class '$this->companylocation_model' not found. strange to me, because I am loading that model in the line before it.
I have also tried escaping the > with a backslash but that also doesn't work.
public function submit($entity) // $entity is set to companylocation during method call
{
$filledEntityObject = $this->getEntityDataFromForm($entity);
$this->load->model($entity . '_model');
$this->companylocation_model->save($filledEntityObject, $filledEntityObject->id);
//call_user_func(array('$this->' . $entity . '_model', 'save'), $filledEntityObject, $filledEntityObject->id);
//call_user_func('$this->' . $entity . '_model->save', $filledEntityObject, $filledEntityObject->id);
...
Expected result is simply being able to call the save method from the model with two parameters in a dynamic way.
Rather than using call_user_func you can build the name using the parts directly into the call...
$this->{$entity . '_model'}->save(...)
I am trying to figure out how to access two (or more) parameters passed to a Laravel controller. I know how to create the route, and the URL is created correctly, but then I can only access the first passed parameter in my controller.
Route:
Route::get('managers/{id}/{parameter2}', array('as'=>'dosomething', 'uses'=> 'ManagersController#dosomething'));
where the first parameter is obviously the $id for managers, and the second parameters is to be processed by the controller.
View:
Do Something
generates the URL:
http://domain/managers/1/2
where 1 is easily accessed as the $id for managers, but when I try to access the 2nd parameter "2" using $parameter2, e.g. using a simple return: "id=$id and parameter2=$parameter2" statement, I get an "unidentified variable: $parameter2" error.
What am I doing wrong?
Is there a better way to pass multiple parameters? I'm especially asking the "better way?" question because what I want to do is use the 2nd parameter to change a value in a database table, and using a 'get' method, somebody could change the parameter value in the URL and therefore cause mischief. Must I use a 'post' method? I'd love to be able to use a link, since that works much better with the design of my application.
Thanks!
I was asked to include the controller, which I'm happy to do. Initially, just for testing, as I mentioned, my controller was a simple return to display the values of the two passed parameters. But here is what I want to be able to do, including the actual name of the function ("update_group" rather than "dosomething") --
ManagersController:
public function update_group($id)
{
DB::table('groups')->where('id','=',$parameter2)->update(array('manager_id'=>$id));
return Redirect::route('managers.show', array('id'=>$id));
}
The update table works perfectly if I replace $parameter2 with an actual value, so that syntax is fine. The issue is that Laravel says that $parameter2 is an undefined variable, despite the fact that the URL contains the value of $parameter2 as you can see above.
And since it occurs to me that the answer to this may involve adding a function to the Manager model, here is the current
Manager.php
class Manager extends Eloquent {
protected $table = 'managers'; ... (mutator and error functions)
}
Just change
public function update_group($id)
to
public function update_group($id, $parameter2)
All looks ok in your route. Seeing the controller code would help, but likely, you may not have a second parameter in your controller's dosomething() method.
public function dosomething($id, $parameter2){
var_dump($id).'<br />';
var_dump($paremter2);
}
If that isn't the case, you can try dumping it from the route's callback to further diagnose.
Route::get('managers/{id}/{parameter2}', function($id, $parameter2)
{
var_dump($id).'<br />';
var_dump($paremter2);
});
Depending on your use case, you can pass them in a query string like so: but it isn't really the 'best way', unless you're doing something like building an API that won't use the same variables in the same order all the time.
/managers?id=1¶mter2=secondParameter
var_dump(Request::query('id')).'<br />';
var_dump(Request::query('paramter2'));
I need your help.
I've just found out that the class \Illuminate\View\Environment has a protected array $sections and a method to get it getSections() but it returns an empty array.
Here's how I tried to get it:
$view = View::make('pages');
$env = $view->getEnvironment();
$env->make('pages');
print($env->getSections());
And the result is Array( )
Where did I go wrong? Any suggestion will be appreciated.
That's because when you call $env->make('pages'), the view isn't immediately processed. It's only processed when the render method on the $view object is called, which is done automatically when you return it as a response, via the __toString() method. The problem, though is that just after the page is rendered, still inside the render method, the $sections variable is cleared, using the flushSections method. So you actually never have access to it.
You could try to fool it if you call the incrementRender method before making the view, then make and render the view, get the sections and then finally decrementRender() and flushSections(), but this could bring unexpected results. Something like this:
// Fool it
$env->incrementRender();
$env->make('pages')->render();
$sections = $env->getSections();
// Clear it
$env->decrementRender();
$env->flushSections();