Laravel controller and adding to the result set - laravel-5

I've checked the Q&A about this and can't find anything, so thought i'd ask.
I have a very simple Laravel controller returning all results from a table as below via the 'Name model'. There is then also a further call to my controller, via the model to count the rows and all works and sends to the result set fine...
// All results from my 'Name' model:
$results = $this->name->getAllResults(); // All works fine.
// I then use my controller again, count the rows via the model and add them to $results:
$results['count'] = $this->countNames(); // Again fine
BUT, when i try to add a string to the $results array before i pass it off to th view, as in:
$results['test'] = 'Test'; // This fails in the view
$results['test'] = 124; // But this passes in the view and renders.
It only seems to allow me to add an INT to my result set array. as $results['test'] = 124 also fails.
I then finally, have this sending to my view via:
return view('names', compact('results')); // And that works fine.
Can anyone see what it is I am missing and why integer added to $results works and not a string?. Many thanks in advance.

You are updating collection data. The following line will give collection of models.
$results = $this->name->getAllResults(); // This may give collection of the model
And below, you are updating the collection object.
$results['count'] = $this->countNames();
You can do the following to safely send data to view, without modifying any.
$results = $this->name->getAllResults();
$count = $this->countNames();
$test = 'Test';
$test2 = 124;
return view('names', compact('results','count','test','test2'));

Related

Laravel filtered collection is no longer filtered after json encoding

I have an Eloquent collection with an eager loaded relationship. When I filter this eager loaded relationship, it works fine, but if I encode it as JSON (to pass it to my front end Javascript framework), the collection is no longer filtered.
Simplified example:
$questions = Question::with('variables')->get();
foreach($questions as $key => $q) {
$questions[$key]->variables = $q->variables->reject(function($v) {
return $v->type == 3;
});
}
dd($questions);
If I look at the $questions variable at this point, my collection is correctly filtered. If, however, I add json_decode(json_encode($questions)) following line before dumping, the collection is no longer filtered.
Note that in my real application, I have to do some things with the rejected variables before throwing them out of the collection, so I cannot simply filter them out during the query.
My workaround right now is to json encode and decode the collection, then do an array filter to get rid of the variables I do not want to pass to the front end. This works, but seems like a terribly inelegant and unnecessary solution. Am I doing something wrong or is this the expected behavior?
I'm still running Laravel 5.8 on this application in the event that this behavior has changed on newer versions.
Why not just load the variables twice then?
$questions = Question::with(['variables' => fn($v) => $v->where('type', '!=', 3)])->get();
// do whatever you need to do with the filtered collection
// reload variables relationship
$questions->load('variables');
// do whatever you need to do with the question and all its variables.
You can try
$questionsWithFilteredVariables = $questions->map(function($question) {
$variables = $question->variables->reject(fn($var) => $var->type === 3);
unset($question->variables);
$question->variables = $variables;
return $question;
});
//Now do json_decode(json_encode(...)), it will still contain filtered variables
$questionsWithFilteredVariables = json_decode(
json_encode($questionsWithFilteredVariables)
);

Getting error as stated below while passing three array values from controller to the view(i.e., to the same page)

Find below the controller code:
public function domaincheck()
{
$response = file_get_contents('https://resellertest.enom.com/interface.asp?command=check&sld=unusualTVname&tld=tv&uid=resellid&pw=resellpw&responsetype=xml');
$data = simplexml_load_string($response);
$configdata = json_encode($data);
$final_data = json_decode($configdata,true);// Use true to get data in array rather than object
// dd($final_data);
$response1 = file_get_contents('http://resellertest.enom.com/interface.asp?command=GETNAMESUGGESTIONS&UID=resellid&PW=resellpw&SearchTerm=hand&MaxResults=5&ResponseType=XML');
$data1 = simplexml_load_string($response1);
$configdata1 = json_encode($data1);
$final_data1 = json_decode($configdata1,true);// Use true to get data in array rather than object
//dd($final_data1);
$response2 = file_get_contents('https://resellertest.enom.com/interface.asp?command=gettldlist&UID=resellid&PW=resellpw&responsetype=xml');
$data2 = simplexml_load_string($response2);
$configdata2 = json_encode($data2);
$final_data2 = json_decode($configdata2,true);
//dd($final_data2);
return view('clientlayout.main.test',array('final_data1' =>
$final_data1), array('final_data' => $final_data),
array('final_data2' => $final_data2));
}
Find the view code given below:
{{print_r($final_data)}}
<br><br><br>
{{print_r($final_data1)}}
<br>
{{print_r($final_data2)}}
Find the route code given below:
Route::get('/test','EnomController#domaincheck');
I need to return all the three arrays to the view page but When use the return view code giveb above I'm getting error as "Undefined variable: final_data2 " for the third array alone.If I declare only two array statements in the return view it works correctly. Suggest me a solution to solve this error.
in addition to #achraf answer if you dont want to use same variable names in your view as of your controller, you can pass data to your view like this. where final1, final2 and final3 will be the names of the variable in your view.
return view('clientlayout.main.test',['final1' =>$final_data ,'final2'=> $final_data1,'final3' => $final_data2]);
View take second param as array, your sending multiple arrays,
the solution is to create an array of arrays like this
return view('clientlayout.main.test',compact('final_data','final_data1','final_data2'));

How to merge two queried results in Laravel Eloquent

I have a single form which I am using to create and edit information.
I am using Form::model to show all the data in the edit form which are queried from the database. Now I had to add another form part whose data is being stored in a different table. But I need to show those data during edit in the same form. I have tried to put two parameter in the form:model which did not work or I am doing it wrong.
{!! Form::model([$employee_data,$edu_info],['route'=>['employee.update',$employee_data->id],'method'=>'put','files'=> true]) !!}
Then I tried to merge the queried data in my controller like this:
public function edit($id)
{
$edit_info['title'] = 'Edit User';
$edit_info['country'] = Country::all();
$employee_basic = Employee::withTrashed()->where('id',$id)->first();
$employee_edu = EmployeeEdu::withTrashed()->where('employee_id',$id)->first();
$employee_all_data = $employee_basic->merge($employee_edu);
$employee_all_data->all();
$edit_info['employee_data'] = $employee_all_data;
return view('admin.employee.edit',$edit_info);
}
This did not work either. I get the following error:
Call to undefined method Illuminate\Database\Query\Builder::merge()
How can I achieve my intended result?
EDIT: I tried to use ->get() instead of ->first(), In this case I do not get the error but my merge does not work as when I dd($employee_all_data) it gives me only the value of $employee_edu.
Try this:
$employee_all_data = $employee_basic->toArray() + $employee_edu->toArray();

View Same user_id

//Anyone can help to create a view data with same id? it is a multiple viewing.
this is my Controller. i dont khow apply in Model and View
function Get_Pitch($id){
$this->load->model('users_model');
$data['query'] = $id;
$this->load->view('view_pitch', $data);
}
Example this is my url "http://localhost/SMS_System/home/sample/102"
in my database is
id=1 name=erwin user_id=102
id=2 name=flores user_id=102
id=3 name=sample user_id=202
how to view the same user_id?
First of all with what you've supplied your URL won't work, you aren't following the normal conventions for CI so it won't know where to look. I am assuming your controller is called sample then you need to tell the application which function you're calling in that controller, finally URL names should be lower case so I changed that, so your URL should read:
"http://localhost/SMS_System/home/sample/get_pitch/102"
Also you need to get your data from a model, you loaded the model then didn't use it. The line after loading the model calls a function from that model and passes it the id you got from your url. Notice the if not isset on the id, this ensures that if someone goes to that page without the id segment there are no errors thrown from the model having a missing parameter, it will just return nothing, that is handled in the view.
Controller:
function get_pitch($id){
//the following line gets the id based on the segment it's in in the URL
$id=$this->uri_segment(3);
if(!isset($id))
{
$id = 0;
}
$this->load->model('users_model');
$data['query'] = $this->users_model->getUserData($id);
$this->load->view('view_pitch', $data);
}
Your model takes the id passed from the controller and uses that to retrieve the data from the database. I normally create the array I am going to return as an empty array and handle that in the view, this makes sure you get no errors if the query fails. The data then returns to the controller in the last line and is passed to the view in your load view call.
Model:
function getUserData($id)
{
$this->db->where('id',$id);
$result = $this->db->get('users') //assuming the table is named users
$data = array(); //create empty array so we aren't returning nothing if the query fails
if ($result->num_rows()==1) //only return data if we get only one result
{
$data = $result->result_array();
}
return $data;
}
Your view then takes the data it received from the model via the controller and displays it if present, if the data is not present it displays an error stating the user does not exist.
View:
if(isset($query['id']))
{
echo $query['id']; //the variable is the array we created inside the $data variable in the controller.
echo $query['name'];
echo $query['user_id'];
} else {
echo 'That user does not exist';
}

codeigniter count_all_results

I'm working with the latest codeIgniter released, and i'm also working with jquery datatables from datatables.net
I've written this function: https://gist.github.com/4478424 which, as is works fine. Except when I filter by using the text box typing something in. The filter itself happens, but my count is completely off.
I tried to add in $res = $this->db->count_all_results() before my get, and it stops the get from working at all. What I need to accomplish, if ($data['sSearch'] != '') then to utilize the entire query without the limit to see how many total rows with the search filter exists.
If you need to see any other code other than whats in my gist, just ask and I will go ahead and post it.
$this->db->count_all_results() replaces $this->db->get() in a database call.
I.E. you can call either count_all_results() or get(), but not both.
You need to do two seperate active record calls. One to assign the results #, and one to get the actual results.
Something like this for the count:
$this->db->select('id');
$this->db->from('table');
$this->db->where($your_conditions);
$num_results = $this->db->count_all_results();
And for the actual query (which you should already have):
$this->db->select($your_columns);
$this->db->from('table');
$this->db->where($your_conditions);
$this->db->limit($limit);
$query = $this->db->get();
Have you read up on https://www.codeigniter.com/userguide2/database/active_record.html#caching ?
I see you are trying to do some pagination where you need the "real" total results and at the same time limiting.
This is my practice in most of my codes I do in CI.
$this->db->start_cache();
// All your conditions without limit
$this->db->from();
$this->db->where(); // and etc...
$this->db->stop_cache();
$total_rows = $this->db->count_all_results(); // This will get the real total rows
// Limit the rows now so to return per page result
$this->db->limit($per_page, $offset);
$result = $this->db->get();
return array(
'total_rows' => $total_rows,
'result' => $result,
); // Return this back to the controller.
I typed the codes above without testing but it should work something like this. I do this in all of my projects.
You dont actually have to have the from either, you can include the table name in the count_all_results like so.
$this->db->count_all_results('table_name');
Count first with no_reset_flag.
$this->db->count_all_results('', FALSE);
$rows = $this->db->get()->result_array();
system/database/DB_query_builder.php
public function count_all_results($table = '', $reset = TRUE) { ... }
The
$this->db->count_all_results();
actually replaces the:
$this->db->get();
So you can't actually have both.
If you want to do have both get and to calculate the num rows at the same query you can easily do this:
$this->db->from(....);
$this->db->where(....);
$db_results = $this->get();
$results = $db_results->result();
$num_rows = $db_results->num_rows();
Try this
/**
* #param $column_name : Use In Choosing Column name
* #param $where : Use In Condition Statement
* #param $table_name : Name of Database Table
* Description : Count all results
*/
function count_all_results($column_name = array(),$where=array(), $table_name = array())
{
$this->db->select($column_name);
// If Where is not NULL
if(!empty($where) && count($where) > 0 )
{
$this->db->where($where);
}
// Return Count Column
return $this->db->count_all_results($table_name[0]);//table_name array sub 0
}
Then Simple Call the Method
Like this
$this->my_model->count_all_results(['column_name'],['where'],['table name']);
If your queries contain a group by, using count_all_results fails. I wrote a simple method to work around this. The key to preventing writing your queries twice is to put them all inside a private method that can be called twice. Here is some sample code:
class Report extends CI_Model {
...
public function get($page=0){
$this->_complex_query();
$this->db->limit($this->results_per_page, $page*$this->results_per_page);
$sales = $this->db->get()->result(); //no table needed in get()
$this->_complex_query();
$num_results = $this->_count_results();
$num_pages = ceil($num_results/$this->results_per_page);
//return data to your controller
}
private function _complex_query(){
$this->db->where('a', $value);
$this->db->join('(subquery) as s', 's.id = table.s_id');
$this->db->group_by('table.column_a');
$this->db->from('table'); //crucial - we specify all tables here
}
private function _count_results(){
$query = $this->db->get_compiled_select();
$count_query = "SELECT count(*) as num_rows FROM (".$query.") count_wrap";
$r = $this->db->query($count_query)->row();
return $r->num_rows;
}
}

Resources