How to Solve "Trying to get property of non-object" in Laravel? - laravel

If my code return null then it generates this error. If the code returns some data, then it works fine.
Controller
$profile_data= DB::table('partner_prefence')
->select('*')
->where('profile_id',$profile_id)
->first();
return view('partner_prefence',['profile_data' => $profile_data]);
View/Blade
#php($rel_status = explode(',', $profile_data->p_marital_status))
If $profile->p_marital_status has a value then there's no issue. The error only comes when its value is null.

Use optional()
https://laravel.com/docs/5.8/helpers#method-optional
If the given object is null, properties and methods will return null instead of causing an error.
{!! old('name', optional($user)->name) !!}

First $profile_data need to be checked whether it is empty or it has some data.
step2: Checking $profile_data object has property called p_material_status.
Step3: If the above both are true then try to explode the data otherwise return some error message and try not explode the data would be better.
<?php
$data = (($profile_data != null) && property_exists($profile_data->p_marital_status)) ? $profile_data->p_marital_status : null)
if($data){
$rel_status = explode(',', $data);
}else{
// Something else
}
?>

Depending on whether the entry is vital for the page to be rendered or not, you could either perform a check in the controller.
$profile_data = DB::table('partner_prefence')
->select('*')
->where('profile_id',$profile_id)
->firstOrFail()
Or allow the null value to pass on to the view and make a ternary check.
$profile_data ? $profile_data->p_marital_status : '';
References:
Ternary Operator
Retrieving Single Models

Simply use an isset() or != null on the sentence like this:
#php($rel_status = $profile_data ? explode(',', $profile_data->p_marital_status?: '')) : [];

Related

How to add validate data search

I am using laravel for this project, i'm newbie at laravel then i want to add validate data if there is true then go to pdf blade, unless the data is false or wrong (i don't know what is it call so i named it True and False, but i hope you understand what i mean)
there is code in controller method search pdf
$id = $request->id;
$date = $request->date;
$pegawai = DB::table('pegawais')
->where('id', $id)
->whereDate('date', $date)
->get();
$pdf = PDF::loadview('pegawai_pdf', [
'pegawai'=>$pegawai
]);
return $pdf->stream();
and this is the output blade when i searched the data is true or exist
here
and this is the output blade when i searched but the data is false or not found data exist
here
fyi the data are fake data from seeder,
From your example, I will assume that you want to check if there is a result or not in $pegawai right? Then just count it.
if (count($pegawai) > 0) {
// show your pdf output here
} else {
// there is no data, do something here
}
to check this does not need to be a true false variable you can check this like this
if($pegawai){
$pdf = PDF::loadview('pegawai_pdf', [
'pegawai'=>$pegawai
]);
return $pdf->stream();
}else{
//show error here
}

Laravel: How to pass a collection to view?

The $result variable displays the json-string correctly. And when I try to send the result to the view, I get an error.
$accreditations = Accreditation::with(['country'])->get();
$result = AccreditationResource::collection($accreditations);
//return $result;
//{"data":[{"id":5,"user_id":1,"login":"Admin","country_id":"4","country":{"id":4,"name":"Austria"}}]}
return View::make('accred_table', $result->login);
//Error 500: Property [login] does not exist on this collection instance.
Help me figure this out
$result is an array. So, there is no login as the error said. If you return only one record from AccreditationResource, you can use
return view('accred_table', ['login' => $result[0]['login']]);
In blade, you will have $login.

Laravel Eloquent - Update() function always return true

Consider the code
return User::find($user_id)->update($data_array)?true:false;
if $data_array have some columns that are not present in User related table.
then also above statement return true.
e.g: $data_array=['not_in_the_table'=>'value'];
return User::find($user_id)->update($data_array)?true:false;
returns true. What is the condition when update returns 0 i.e. false?
If you use where('id','=',$user_id) like below instead of find($id), you will get error like Column not found for the columns that are not present in User related table. So it is best way to do this :
User::where('id','=',$user_id)->update(['column_name'=>'value']);
Instead of :
User::find($user_id)->update($data_array)?true:false;
Update method always return int. For more info Check Here
or If you want to update the the record by using Object Relation Mapping way then you can do like this :
$user = User::find($user_id) ;
$user->column_name = 'value';
if($user->save()){
//do something when user is update
}else{
// do something wehn user is not update
}
You cannot get error into false there because validation of Laravel use library.
For Laravel 4.2
public function update($user_id) {
$data_array = Input::all();
$validator = Validator::make(
$data_array,
array('name' => 'required|min:5')
);
if ($validator->passes()) {
// success as true
User::find($user_id)->update($data_array)
} else {
//failed as false
}
}
For more information about validator
I hope this help you

Only update field if form value exists

I'm using Form Model Binding as such and updating my DB using the fill() and save() methods.
{{ Form::model($account) }}
{{ Form::text('name', null, array('class'=>'class')) }}
{{ Form::text('email', null, array('class'=>'class')) }}
{{ Form::password('password', array('class'=>'class')) }}
{{ Form::password('password_confirmation', array('class'=>'class')) }}
{{ Form::close() }}
Which fires my editAccount controller method:
$rules = array(
'name' => array('required'),
'email' => array('required'),
'password' => array('confirmed')
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
// Redirect
}
// Save to DB
$account->fill(Input::all());
$account->save();
Which works fine, but if no password was supplied (because the user doesn't want to update/modify it) then the password field is set to null in the db. So, I only want the password field to update if a new password value is supplied via the form.
I know I can do the following:
// Set the fields manually
$account->name = Input::get('name');
$account->email = Input::get('email');
// Only update the password field if a value is supplied
if (Input::get('password')) {
$account->password = Input::get('password');
}
$account->save();
However I'm wondering if there is a more cleaner way to handle this? Like an UpdateOnlyIfValueExists() method within Laravel/Eloquent.
Using Input::only('foo', 'bar') will grab only the values needed to complete the request - instead of using Input::all().
However, if 'foo' or 'bar' doesn't exist within the input, the key will exist with the value of null:
$input = Input::only('foo', 'bar');
var_dump($input);
// Outputs
array (size=2)
'foo' => null
'bar' => null
To filter in a clean way, any values with a null value:
$input = array_filter($input, 'strlen');
In your example, this would replace: $account->fill(Input::all());
Create Base model and override update function like
/**
* #param array $attributes
* #return mixed
*/
public function update(Array $attributes = array()){
foreach($attributes as $key => $value){
if(!is_null($value)) $this->{$key} = $value;
}
return $this->save();
}
After use:
$model = Model::find($id);
$model->update(Input::only('param1', 'param2', 'param3'));
Check this, you can validate if password is present in input, and exclude it from mass assignment. You can use Input::except and Input::only for this purpose
public function update ($id) {
$user = User::findOrFail ($id);
if (Input::get ('password') == '') {
$user->update (Input::except ('password'));
}
else {
$user->update (Input::all ());
}
//return something
}
$data = $request->password ? $request->all():$request->except('password');
$user->update($data);
This will only update the password if it's not null
I would stick with your latter example. Another option would be to use a mutator which checks the value there, and doesn't update if the value is empty. But in my opinion, Eloquent should not be responsible for doing that.
I'd also avoid using ALL input with fill(). Choose only what you want.
This is a pretty shitty and common issue with Laravel (and other frameworks). My solution resembles some of the previous...
I always have the form data Input::all() stored in a variable at the beginning of the update/store methods. Since you usually need it at least twice (validate and create/update) it seems like a good practice. Then with that and before doing anything else I check in update() for the presence of the password, something like this:
$aFormData = Input::all();
if ( !$aFormData['password'] )
unset( $aFormData['password'] );
... the rest of your code here using $aFormData ;) ...
And that's it, hope it helps!
A much cleaner approach would be to use Eloquent Mutators
Under no circumstances would you allow a null or an empty string as password so you can safely define the following mutator in your Account model.
// Only accept a valid password and
// hash a password before saving
public function setPasswordAttribute($password)
{
if ( $password !== null & $password === '' )
{
$this->attributes['password'] = bcrypt($password);
}
}
The above mutator will only set a password attribute if it is not null and an empty string. It also hashes the password before saving so you do not need to do it in your controller action or application elsewhere.
Best approche is to use mutators as Noman Ur Rehman said above, but he had mistake in his code. Right one will be:
public function setPasswordAttribute($password){
if ( $password !== null && $password !== '' )
$this->attributes['password'] = Hash::make($password);
}

Is there a shorter way than this to check values when using same Add form for Edit

I have the same code for an Add and an Edit form. Therefore in the controller I need a check to check if a) POST vars submitted (for saving), and if not then b) the original values (for editing) and if not then no value (blank for Adding). I put them in a $data array to pass to the view. Then in the form I can put:
value="<?php echo $member_id;?>"
So my question is, in Codeigniter is there a shorter way than the following to check if POST, then if not check if the original data exists, and if not then its nothing.
$data = array(
'member_id' => ( isset($_POST['member_id']) ? $_POST['member_id'] : (isset($member->member_id ) ? $member->member_id : '') )
);
I know about set_value() but looks like that wont add in the current data when editing a form, so have not used that.
You can allways make function for it.
function get_value_or_default($array, $key, $default) {
return isset($array[$key] ? $array[$key] :
isset($default) ? $default : '';
}
Or even better:
function update_from_post($object) {
$data = array();
foreach ($object as $prop_name => value) {
$value = get_value_or_default($_POST, $prop_name, $object->{$prop_name});
$data[$prop_name] = $value;
}
Assuming you have different methods in the controller for create vs edit: (you can use the same view in different methods by specifying it in $this->load->view()):
Your create method would assume it was new, and always read the $_POST variables (if $_POST)
Your edit method would first load the object from the database, and then overwrite with $_POST variables if present.
Finally, CodeIgniter has the input helper:
$this->input->post('field_name');
returns false if that field is not in $_POST.
To use your code above:
create
$data = array(
'member_id' => $this->input->post('member_id') ? $this->input->post('member_id') : '')
);
edit
$data = array(
'member_id' => $this->input->post('member_id') ? $this->input->post('member_id') : $member->member_id )
);

Resources