Laravel collection display and short issue - laravel

Hello guys!
I have a a little problem with collections. I have never worked with these. I would like to display a collection at my welcome blade but there is a problem. My collection is not in the contrroller, the collection's place is in the App/Repositories/xyz.php and in a function. How can i pass this function to the controller and after show it at the welcome blade??
App/repositories/xyz.php
public function getcars(): Collection
{
return collect([
new Car(...)
)];
controller
public function __invoke(): View
{
return view('welcome', ['cars' => collect([
new Car() ------> I would like to put datas from xyz.php repo here
new Car()
new Car()
....
And welcome.blade file where i would like to display
<div class="car-list">
<h2>{{ $title }}</h2>
#foreach($cars as $car)
<x-car :car="$car" />
#endforeach
</div>

You could do that in many ways:
Creating new instance
use App\repositories\Xyz;
public function __invoke(): View
{
$repo = new Xyz();
return view('welcome')->with('cars', $repo->getcars());
}
Pulling your class from the container
use App\repositories\Xyz;
public function __invoke(): View
{
$repo = app(Xyz::class);
return view('welcome')->with('cars', $repo->getcars());
}
Using dependency injection to resolve it from container
use App\repositories\Xyz;
protected Xyz $repo;
public function construct(Xyz $xyz): View
{
$this->repo = $xyz;
}
public function __invoke(): View
{
return view('welcome')->with('cars', $this->repo->getcars());
}

I believe from your Controller file, you can create an object property of your Repository via __construct() method like this:
protected MyRepository $myRepository;
public function __construct(MyRepository $myRepository)
{
$this->myRepository = $myRepository;
}
Then, you can call $this->myRepository's method from there, for example like getting records, etc. Then you can pass the result to your view.

Related

Call To A Member Function On String

Hello Guys I Have This Function In My Model
public function photo () {
return $this -> photo;
}
And I Called The Function From My Blade
{{$model = \App\Models\mainCategory::class}}
<td> <img style="width: 150px; height: 100px;" src="{{asset('assets/images/main-categories/' . $model -> photo() // Here I Have an Error `Call to a member function photo() on string` )}}"></td>
I Have This Error Call to a member function photo() on string
use App\Models\mainCategory;
class YourController extends Controller
{
public function index(){
return view('your_view', ['category' => mainCategory::first() ];
}
}
Then in your blade file, you do:
$category->photo
Instead of your current model->photo()
This line {{$model = \App\Models\mainCategory::class}} is wrong. You have first to retrieve the model from the database, to use the model attributes.
For example
{{$model = \App\Models\mainCategory::first()}} or
{{$model = \App\Models\mainCategory::find($id)}}.
Another thing to point, since you have the attribute photo already existing, why would write a method, that returns the same thing. You can use $model->photo directly.
Another thing, it's not recommended to retrieve data from the database, while you're in the view, you have the controller to do so.

Laravel using where clause on Views

I'm newbie on Laravel.
I can send data like that:
public function index()
{
$InboxNew = Models\Inbox::where('read', false)->get();
$InboxMarkedAsRead = Models\Inbox::where('read', true)->get();
return view('dashboard.inbox', compact('InboxNew', 'InboxMarkedAsRead'));
}
I want to get data in view like that but gives some errors:
public function index()
{
$Inbox = Models\Inbox::all();
return view('dashboard.inbox', compact('Inbox'));
}
In view:
#if($Inbox->where('read', false)->get())
...
#endif
Your controller :
public function index()
{
$Inbox = Models\Inbox::all();
return view('dashboard.inbox', compact('Inbox'));
}
In blade you can achieve your data like this way :
#foreach($inbox as $query)
#if($query->read == false)
//
#endif
#endforeach
Problem with your code is that you have already called all() method on the Models\Inbox. What all() do is to simply call the get() method on model without applying any conditions.
You either need to define only a model (via query() method:
// Controller
public function index()
{
$Inbox = Models\Inbox::query();
return view('dashboard.inbox', compact('Inbox'));
}
and fetch it later with where clauses In view:
#if($Inbox->where('read', false)->get())
...
#endif
OR
You can do it in a cleaner way, which is to fetch the data in controller and use the view only to show the data
You either need to define only a model (via query() method:
// Controller
public function index()
{
$Inbox = Models\Inbox::where('read', false)->get();
return view('dashboard.inbox', compact('Inbox'));
}
and fetch it later with where clauses In view:
#if($Inbox)
...
#endif
PS: To check if a record exists, use exists() method instead of get() e.g $Inbox->exists()

Rendering blade components via AJAX doesn't initiate component attributes and methods

I have a Blade Component class like this:
class RolesSelect extends Component
{
public $roles;
public $user;
public function __construct($roles = null, $user = null)
{
//... some logic goes here (irrelevant)
}
public function isSelected($user,$role)
{
// ... some logic
}
public function render()
{
return view('components.roles-select');
}
}
When I render my component as usual <x-roles-select></x-roles-select> everything goest fine.
But here starts the problem: when I load the component via AJAX, I use the view('components.roles-select')->render(). And the component can't see the isSelected method anymore.
It throws this error: Undefined variable: isSelected
I tried to research the Blade and Component classes, but only came this far:
$roleSelect = new RolesSelect($roles, $user);
$roleSelect->resolveView()->render();
I can access everything, but the isSelected method.
I was close enough. Dabbled a bit with the code, and got it working!
In my controller (or just the route method), you have to initialise the component class, and pass it's data to the view like this:
$roleSelect = new RolesSelect($roles, $user);
if (request()->wantsJson()) {
return response()->json([
'content' => $roleSelect->resolveView()->with($roleSelect->data())->render()
],200);
}

laravel model controller retrieve data

I'am new to laravel and had a hard time for eloquent ORM, I like to retrieve Favourite items from the table with specific user id, but seem I don't find a way to display the data correctly.
I refer and copied the favourite model code from here
Model: Favourite
class Favourite extends BaseModel
{
public function favouritable()
{
return $this->morphTo();
}
}
Model: Course
public function favourites()
{
return $this->morphMany(Favourite::class, 'favouritable');
}
public function myFavourite()
{
return $this->favourites()->where('favor_user', '=', auth()->user()->id);
}
Controller: FavouriteController#index
public function index()
{
$course = new Course();
$myfavs = $course->myFavourite();
//dd($myfavs);
$this->vdata(compact('myfavs'));
return view('front.favorites', $this->vdata);
}
In blade view, but return empty/blank data:
#foreach($myfavs as $myfav)
{{ $myfav->$course_name }}
#endforeach
When i dd($myfavs) it display pretty bunches of data that i couldn't find the data that is stored in the favourites table.
I think you have added the conditions but forgot get the results with one of the methods to do so.
Try :
$myfavs = $course->myFavourite()->get();
Or :
$myfavs = $course->myFavourite()->take(<N>)->get;
Or
::all()
etc. take a look at : https://laravel.com/docs/5.8/eloquent#retrieving-models

How to use multiple routes that link to same page in laravel?

I have 2 controllers. One manages category and other slider. They have no relation between them. They are on same homepage in different sections. So I want to show both category and slider value that is there in database.
I tried
Route::get('/', ['uses'=>'SliderController#homepage','as'=>'homepage']);
Route::get('/', ['uses'=>'CategoryController#homepage','as'=>'categoryHomepage']);
If I do that the second one is overwriting the first one.
Is there a way from which I can pass both routes so that I can use both values in my homepage.
Thanks!
Have you tried dependency injection.
1 Single route
Route::get('/home', ['uses'=>'SliderController#index','as'=>'homepage']);
2 Create a data passing controller
use View;
class SliderController extends Controller {
private $repository;
public function __construct(DataRepository $repository)
{
$this->repository = $repository;
}
public function index(DataRepository $repository)
{
return View::make('home.index')->with('data', $this-repository->getData());
}
}
3 DataRepository class fetch there records
class DataRepository {
public getData()
{
$data = array();
$data['category'] = Category::all();
$data['slider'] = Slider::all();
return $data;
}
}
After above three steps, DataRepository will automatically inject data to your controller. Reference taken from here.

Resources