Laravel issue- "Trying to get property of non-object" - laravel

Controller :
$args = array();
$args['name'] = "Robin";
$args['email'] = "asdasd#asdasd.net";
$clientpayments = Payments::getPaymentByClient($id);
$args['activity'] = $clientpayments;
return view('clients.show',["args" => $args]);
View:
{{ $args->name }}
{{ $args->email }}
#if (isset($args['activity']))
#foreach ($args['activity'] as $act)
{{$act->job_name}}
#endforeach
#endif;
So what the issue is is that $activity loop works fine but the $name and $email is returning a non-object error... Any ideas to where I'm going wrong?
Thanks!

Since you're using an array, change this:
{{ $args->name }}
{{ $args->email }}
To:
{{ $args['name'] }}
{{ $args['email'] }}

You are trying to access an object value, but you are sending an array to your view.
$payments = Payments::getPaymentByClient($id);
$args = array([
'name' => 'Robin',
'email' => 'asdasd#asdasd.net',
'activity' => $payments, // Expecting a collection
]);
return view('clients.show', [
"args" => (object) $args // Cast into an object
]);
Blade template (if you have an object)
{{ $args->name }}
{{ $args->email }}
// If your activity is a collection
#foreach ($args->activity as $act)
{{ $act->job_name }}
#endforeach
Blade template (if you have an array)
{{ $args['name'] }}
{{ $args['email'] }}
// If your activity is a collection
#foreach ($args['activity'] as $act)
{{ $act->job_name }}
#endforeach

Got it.
A silly mistake, but I'm just learning Laravel. I was including $args in the View rather than just $name, $email and $activity which worked perfectly.
Thanks anyway.

Related

How to display specific data from array?

How can I correct display data from array. I guess it's a foreach loop, but I do not know how to bite it. I just need only header. It's in table calendars.
Thanks so much!
#foreach($list as $item)
{{ $item->header }}
#endforeach
I tried the above code but throws out an error, unknown value "header"
#foreach($results as $type => $list)
<div class="single-contact-information mb-30">
<h3>{{ $type }} </h3>
{{ $list }}
</div>
#endforeach
[{"id":1,"header":"test","description":"<p>test<\/p>","date":"2020-12-12"}]
Edit:
SearchController:
public function search(Request $request)
{
$search = $request->get('search');
$results = [];
$results['calendars'] = DB::table('calendars')->where('header', 'like', '%'.$search.'%')->get();
return view('pages.search', ['results' => $results]);
}
You should try this:
[{"id":1,"header":"test","description":"<p>test<\/p>","date":"2020-12-12"}]
Above value is json then use below code
$list = [{"id":1,"header":"test","description":"<p>test<\/p>","date":"2020-12-12"}];
#foreach($list as $item)
{{ $item['header'] }}
#endforeach
$list = json_decode($list);
#foreach($list as $item)
{{ $item['header'] }}
#endforeach
Updated Answer
#foreach(json_decode($list) as $item)
{{ $item->header }}
#endforeach
try this one
used json_decode function here
#foreach(json_decode($list) as $item)
{{ $item['header'] }}
#endforeach

Update Data in Laravel

This is my code :
Route:
Route::get('/editposts/{id}', function ($id) {
$showpost = Posts::where('id', $id)->get();
return view('editposts', compact('showpost'));
});
Route::post('/editposts', array('uses'=>'PostController#Update'));
Controller :
public function Update($id)
{
$Posts = Posts::find($id);
$Posts->Title = 10;
$Posts->Content = 10;
$Posts->save();
//return Redirect()->back(); Input::get('Title')
}
and View:
#foreach($showpost as $showpost)
<h1>Edit Posts :</h1>
{{ Form::open(array('url'=>'editposts', 'method'=>'post')) }}
Title : {{ Form::text('Title', $showpost->Title) }} <br> Content : {{ Form::text('Content', $showpost->Content ) }} <br> {{ Form::submit('Update') }}
{{ Form::close() }}
#endforeach
but when I want to Update my data i receive an error :
http://localhost:8000/editposts/1
Missing argument 1 for App\Http\Controllers\PostController::Update()
You need to change route:
Route::post('editposts/{id}', 'PostController#Update');
Then the form to:
{{ Form::open(['url' => 'editposts/' . $showpost->id, 'method'=>'post']) }}
Change your post route to:
Route::post('/editposts/{id}', 'PostController#Update');
Done!
Correct the route,specify a parameter
Route::post('editposts/{id}', 'PostController#Update');
Pass the post'id as paramater
{{ Form::open(array('url'=>'editposts/'.$post->id, 'method'=>'post')) }}
Title : {{ Form::text('Title', $showpost->Title) }} <br> Content : {{ Form::text('Content', $showpost->Content ) }} <br> {{
Form::submit('Update') }}
{{ Form::close() }}
Notice $post->id
First declare your route:
Route::post('/editposts/{id}', array('uses'=>'PostController#Update'));
Then update your form url:
{{ Form::open(['url' => url()->action('PostController#Update', [ "id" => $showpost->id ]), 'method'=>'post']) }}
This is assuming your model's id column is id
(Optional) You can also use implicit model binding :
public function Update(Posts $id) {
//No need to find it Laravel will do that
$id->Title = 10;
$id->Content = 10;
$id->save();
}

eloquent create not inserting everything

I want to insert a row in my database using the input from a form.
//PersonController
Public function store(){
$input = Input::all();
if(! $this->person->fill($input)->isValid()){
return Redirect::back()->withInput()->withErrors($this->person->messages);
}
$this->person->create($input);
}
//class Person
protected $fillable = ['name', 'group_id', 'email', 'phone', 'address', 'isresponsible'];
public $messages;
public function isValid(){
$validation = Validator::make($this->attributes, static::$rules);
if ($validation->passes()) return true;
$this->messages = $validation->messages();
return false;
}
//Form in View
{{ Form::open(array('action' => 'PersonController#store')) }}
{{ Form::text('name') }}
{{$errors->first('name', '<span class=error>:message</span>')}}
{{ Form::select('group', $groups, Input::old('id')) }}
{{ Form::email('email') }}
{{ Form::text('phone') }}
{{ Form::text('address') }}
{{ Form::checkbox('isResponsible') }}
{{ Form::submit('Create') }}
{{ Form::close() }}
The sql statement generated by
$this->person->create($input)
is missing the foreign key (group_id) and the boolean value (isresponsible)
That's because the names in your form don't match the names of the attributes in the database.
isResponsible ≠ isresponsible
group ≠ group_id
Simply change the names in your form:
{{ Form::select('group_id', $groups, Input::old('group_id')) }}
{{-- ... --}}
{{ Form::checkbox('isresponsible') }}

Laravel pre-filling multiple forms if validation failed

One of the coolest Laravel feature is, Laravel pre-filled the form fields if validation error occurred. However, if a page contain more than one form, and form fields have same name, Laravel pre-filling all forms fields.
For example:
I have a page where i have two forms to create new users or whatever.
<h1>Create user1</h2>
{{ Form::open(array('url' => 'foo/bar')) }}
{{ Form::text('name', null) }}
{{ Form::email('email', null) }}
{{ Form::close() }}
</h1>Create user2</h1>
{{ Form::open(array('url' => 'foo/bar')) }}
{{ Form::text('name', null) }}
{{ Form::email('email', null) }}
{{ Form::close() }}
Controller
class UsersController extends BaseController
{
public function store()
{
$rules = [
'name' => 'required',
'email' => 'required'
];
$validation = Validator::make(Input::all(), $rules);
if ($validation->fails()) {
return Redirect::back()->withInput()->withErrors($validation);
}
}
}
As i didn't fill up the email, Laravel will throw validation error and pre-filling the forms as following:
How to tell Laravel that do not fill-up the second form?
There's no Laravel way of doing this, but you can use HTML basic form arrays to make it work. You need to understand that you have to identify your forms and fields so Laravel knows exactly where the data came from and where to send it back to. If all your fields have the same name how could it possibly know?
This is a proof of concept that will work straight from your routes.php file.
As I did it all and tested here before posting the answer I used Route::get() and Route::post(), to not have to create a controller and a view just to test something I will not use. While developing this you will have to put this logic in a controller and in a view, where I think they are alredy in.
To test it the way it is, you just have to point your browser to the following routes:
http://yourserver/form
and when you push a button it will automatically POST tho the route:
http://yourserver/post
I'm basically giving all forms a number and giving the buttons the number that we will usin in Laravel to get the form data and validate it.
Route::get('form', function()
{
return Form::open(array('url' => URL::to('post'))).
Form::text('form[1][name]', null).
Form::email('form[1][email]', null).
'<button type="submit" name="button" value="1">submit</button>'.
Form::close().
Form::open(array('url' => URL::to('post'))).
Form::text('form[2][name]', null).
Form::email('form[2][email]', null).
'<button type="submit" name="button" value="2">submit</button>'.
Form::close();
});
And here we get the data, select the form and pass all of it to the validator:
Route::post('post', function()
{
$input = Input::all();
$rules = [
'name' => 'required',
'email' => 'required'
];
$validation = Validator::make($input['form'][$input['button']], $rules);
return Redirect::back()->withInput();
});
This is how you use it in a Blade view, now using 3 forms instead of 2 and you can have as many forms as you need:
<h1>Create user1</h2>
{{ Form::open(array('url' => URL::to('post'))) }}
{{ Form::text('form[1][name]', null) }}
{{ Form::email('form[1][email]', null) }}
<button type="submit" name="button" value="1">submit</button>
{{ Form::close() }}
</h1>Create user2</h1>
{{ Form::open(array('url' => URL::to('post'))) }}
{{ Form::text('form[2][name]', null) }}
{{ Form::email('form[2][email]', null) }}
<button type="submit" name="button" value="2">submit</button>
{{ Form::close() }}
</h1>Create user3</h1>
{{ Form::open(array('url' => URL::to('post'))) }}
{{ Form::text('form[3][name]', null) }}
{{ Form::email('form[3][email]', null) }}
<button type="submit" name="button" value="3">submit</button>
{{ Form::close() }}
And you can even use a loop to create 100 forms in blade:
#for ($i=1; $i <= 100; $i++)
User {{$i}}
{{ Form::open(array('url' => URL::to('post'))) }}
{{ Form::text("form[$i][name]", null) }}
{{ Form::email("form[$i][email]", null) }}
<button type="submit" name="button" value="{{$i}}">submit</button>
{{ Form::close() }}
#endfor
Use old input with $request->flash().
https://laravel.com/docs/5.2/requests#old-input

HasMany relationship old input

I have a model Category. Category has many Localization. When I store Category, I have these inputs:
{{ Form::text('title[en]', Input::old('title')) }}
{{ Form::text('title[ru]', Input::old('title')) }}
Which I store like this in my controler:
// Gett all inputs
$inputs = Input::all();
// Create resource
$item = Category::create([]);
// Create localization
foreach(Input::get('title') as $locale => $title)
{
$locale = new Localization(['locale' => $locale, 'title' => $title]);
$locale = $item->localization()->save($locale);
}
That works great but what is the best practise for updating such relationships? Currently I'm trying that with Form::model binding.
#foreach($locales as $key => $locale)
{{ Form::text('title['.$locale.']', $model->translate($locale)->title, ['class' => 'form-control']) }}
#endforeach
I have no idea how Input::old could work in this situation, so now I'm using $model->translate($locale)->title to get the correct value. Basically the updating/validation part doesn't really work. What you could suggest to change to validate such relationship and update it?
Today I found a working solution storing/updating relationships with validation. I hope it's the best/simplest way to do that. I created a new array with inputs for validation and changed in the view errors accordingly.
This is my update controller.
public function update($id)
{
// Find resource
$item = Category::find($id);
foreach(Input::get('title') as $locale => $title)
{
$v['title_'.$locale] = $title;
}
// Attempt validation
if($item->validate($v))
{
foreach(Input::get('title') as $locale => $title)
{
$localization = $item->translate($locale);
$localization->title = $title;
$localization->save();
}
return Redirect::action('AdminCategoryController#edit', [$item->id]);
}
else
{
// Failure, get errors
$errors = $item->errors();
return Redirect::back()
->withInput()
->with('errors', $errors);
}
}
And this is the update view;
{{ Form::model($model, ['action' => ['AdminCategoryController#update', $model->id], 'method' => 'PUT']) }}
#foreach($locales as $key => $locale)
<div id="{{ $locale }}">
<div class="form-group">
{{ Form::label('title['.$locale.']', _('admin.title_'.$locale)) }}
{{ Form::text('title['.$locale.']', $model->translate($locale)->title, ['class' => 'form-control']) }}
#if($errors->has('title_'.$locale))
<div class="help-block alert alert-danger">{{ $errors->first('title_'.$locale) }}</div>
#endif
</div>
</div>
#endforeach
{{ Form::close() }}
This way you can easily CRUD, validate all types of relationships (input arrays) in Laravel.

Resources