Trying to take some data from my file called "listing-card" which is is saved in the component folder - laravel-9

#foreach($listings as $listing)
<x-listing-card :listing="$listings" />
#endforeach
the listing card is in the component file
I was expecting to get results from 'listing-card' blade file. but I got this error
enter image description here

without a better understanding of your code, the first thing I see is the :listing=$listings
I would think you would want the individual item $listing from your foreach.
Secondly, The error states it can not find the class. Be wary of kabob-case vs CamelCase. It has bitten me a few times
Edit/Update addressing comment below:
You will have to go and look at your component blade file to check on your exact naming convention you are using. For example you have a class named SiteInfo and in the render section you would have it return something like : return view('components/site-info');
Your file and class being used will be SiteInfo.blade.php and the class in it will be: class SiteInfo extends Component
example:
#foreach($listings as $listing)
<x-listing-card :listing="$listing" />
#endforeach
Your Class file would be something similar to:
class Listing-card extends Component
{
public $listing;
}
/**
* Create a new component instance.
*
*
*/
public function __construct($listing)
{
$this->listing = $listing;
}
/**
* Get the view / contents that represent the component.
*
* #return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
return view('components.listing-card');
}
}
You might have to enable some logging at key points in your app and pull data. The laravel log /storage/logs/laravel.log is invaluable in find your mistakes.

Related

Laravel-8 Related data in a collection is lost

I am trying to get more familiar with laravel/livewire. I find myself struggling with collections with related data. In my component i get data from the database and store it in a variable, with related data. When i do a dd after the retrieval, i see a complete collection with the related data. In my bladefile i have a foreach loop to display all the lists and for each list i have a foreachloop to display all todos.
But when i want to edit a list, i want to show one of the lists in a modal with a form. I call a function 'edit_todo' and i want to extract the data from my collection to fill in a blade form.
But when i look at the same variable as before ($this->todolists) in that function, the related data is missing.
This is a part of the code.
class Dashboard extends Component
{
public $todolists, $list_id, $todolist;
public function render()
{
$this->todolists = TodoList::with('todos')->get();
//dd($this->todolists); //<-- relationsproperty shows all todos from each list
return view('livewire.dashboard');
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
public function edit_todo($list_id)
{
dd($this->todolists); //<-- relationsproperty is empty
$this->todolist = $this->todolists->where('id',$list_id)->with('todos')->first()->toArray();
}
Any suggestions? What am i doing wrong?
Maybe i just have to get the data again from the database, but i'd like to understand why this isn't working.
Move the population of your $todoLists to the mount method:
public function mount()
{
$this->todolists = TodoList::with('todos')->get();
}
Have a look at https://laravel-livewire.com/docs/2.x/lifecycle-hooks and you'll notice that the render method is only requested at the very end. If you need your $todoLists populated as you wish, move it up in the list of lifecycle hooks.
Edit & extra: mount() in LiveWire is equal to __construct() in any other class as we are used to. Whatever you would like to 'construct', write it in the mount method.

Too few arguments to function Livewire\LivewireManager::mount(), 0 passed in

Thanks in advance for helpful advice. I am using Laravel Livewire for creating components and Jetstrap for authentication for those routes that require it.
At the moment I only have one route set up for testing authentication, yet after I have logged in to view that route, I get the following error:
Too few arguments to function Livewire\LivewireManager::mount(), 0 passed in /var/www/mvp/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 261 and at least 1 expected
This seems to be originating from the LivewireManager class, inside the getInstance() function:
public function getInstance($component, $id)
{
$componentClass = $this->getClass($component);
throw_unless(class_exists($componentClass), new ComponentNotFoundException(
"Component [{$component}] class not found: [{$componentClass}]"
));
return new $componentClass($id);
}
It seems to be expecting a component argument from the Facade class in /vendor/laravel/framework/src/Illuminate/Support/Facades/, but isn't getting the component it needs. I checked the page code, and there is definitely a component there.
The Facade function creating the error:
/**
* Handle dynamic, static calls to the object.
*
* #param string $method
* #param array $args
* #return mixed
*
* #throws \RuntimeException
*/
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
And the page that's supposed to be loading its component:
#extends('layouts.app')
#section('content')
#livewire('component')
#stop
Is there a simple way to fix the problem? Or am I missing something?
I got same error like what you get when i try to passing parameter and then i'm solving the problem by following the documentation with changing the way to render livewire component from using blade directive #livewire() into <livewire: >

pass data to another route without messing with url

DISCLAIMER: I'm a noob.. sorry
Say I have 2 different components that are siblings:
comp1 and comp2
I wish to route from comp1 to comp2 with a bunch of data. How can I achieve this without getting a fugly url-bar containing everything?
I've tried using a separate class, lets call it DataTransmitter:
data-transmitter.js:
export class DataTransmitter {
constructor() {
this.val= "a";
}
}
comp1.js:
import { DataTransmitter } from './data-transmitter';
#inject(DataTransmitter)
export class comp1{
constructor(DataTransmitter){
this.DataTransmitter = DataTransmitter;
}
someMethod(){
this.DataTransmitter.val = "b";
console.log('comp1: ' + this.DataTransmitter.val);
}
}
comp2.js:
import { DataTransmitter } from './data-transmitter';
#inject(DataTransmitter)
export class comp2{
constructor(DataTransmitter){
this.DataTransmitter = DataTransmitter;
}
someMethod(){
console.log('comp2: ' + this.DataTransmitter.val);
}
}
This gives me the output:
comp1: b
comp2: a
I've also tried messing around with EventAggregator, but no success.
Is there some way of routing with parameters WITHOUT having a url that looks like site/comp2?data=stuff&things=otherstuff&params=values&more=etc?
You absolutely want to use a singleton class and then inject it inside of whatever components you need your data. The link that Gaby posted is definitely what you want to do.
The reason your posted code does not work is because you're attempting to use the inject decorator, but you're not importing it. Please see this working example of what you are trying to do on Gist.run here. I have two components, you can click to route between them and set the value. You'll notice the set value remains when you navigate back and forth.

Set the default __toString() format per Carbon instance?

I retrieve dates from a database and have the option to pre-process them (via the Laravel framework (v5.2)). The dates or times can come in any particular format but for this example let's say Y-m-d.
I want to be able to access the date as a Carbon instance in the view — this would give me the flexibility to format the date however I please or do nothing with it and print as-is (with the default toString being the same as its original string format).
The issue is maintaining the default expected toString format at the top-level Carbon toString format.
According to the docs, you can use the ::setToStringFormat() method to change the default format of toString. It is possible to set it with the static method Carbon::setToStringFormat() but it also works as an instance method e.g. ($date = Carbon::now())->setToStringFormat('Y-m-d') - albeit this seems to behave identically to the static method.
So, is it possible to set the individual __toString() format for a date instance?
It would allow me to do the following:
public function getDateAttribute($value)
{
$date = Carbon::createFromFormat('Y-m-d', $value);
// $date->setToStringFormat('Y-m-d');
return $date; // prints in 'Y-m-d' format
}
In a view, I would then chain methods on the date, or print it as-is.
I had the same sort of issue and worked my way around it
First create a global serialization method for carbon dates (e.g. in the boot of the Laravel AppServiceProvider)
<?php
namespace App\Providers;
use Illuminate\Support\Carbon;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
// ...
Carbon::serializeUsing(function (Carbon $carbon):string {
$format = $carbon->getSettings()['toStringFormat'] ?? 'Y-m-d\TH:i:s';
return $carbon->format($format);
});
// ...
}
// ...
}
Then set the 'toStringFormat' setting to the format you need
$someCarbonDate->settings([ 'toStringFormat' => 'Y-m-d' ]);
Carbon::serializeUsing will now check if the carbon being serialized has a toStringFormat and use that or it will fall back to some other format you define.
You could probably also create your own Carbon class and extend Carbon\Carbon or Illuminate\Support\Carbon (used by Laravel) and override the __toString method, but that creates some new challenges when used in combination with the casting Laravel does internally.
If you just want to set the default format for when rendering Blade templates you can use the Blade::stringable method.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
// ...
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
// ...
Blade::stringable(function(\Illuminate\Support\Carbon $dateTime) {
return $dateTime->format('d/m/Y H:i:s');
});
// ...
}
// ...
}
Any Illuminate\Support\Carbon instances should automatically be rendered with this format unless you choose otherwise.
For example...
{{ $user->created_at }} would now render as 23/07/2021 10:16:24 by default
{{ $user->created_at->toDateString() }} still works and would render as 23/07/2021
NOTE: You might need to run php artisan view:clear to clear any compiled views before this takes effect 🙂

Can't get data from a static array in HelperAdmin

I have a file/class::method (HelperAdmin.php/HelperAdmin::menuItem()) which extracts data from DB to generate main menu and submenu.
I have to get this data after the menu being generated but I don't want to call this method twice.
So I have created a static array in HelperAdmin class. It looks like this:
class HelperAdmin {
static $arrMenuItems;
...
public static function menuItem() {
....get $items....
self::$arrMenuItems = $items;
return $items;
}
....
}
But here is a problem. If I call the METHOD again:
$items=HelperAdmin::menuItem();
...I can get data.
In other hand if I try to get data through a static array:
$items=HelperAdmin::$arrMenuItems;
...it just returns null.
I hope to see some ideas. After all, if your opinion is that using static variable here (from Yii architecture view) is not the best solution, I'd like to get your advice!
#bool.dev:
OK, imagine the following scheme:
1. We have the main file
/modules/admin/views/layouts/admin.php
which is in essence our backend template.
2. We have the helper here:
/modules/admin/components/HelperAdmin.php
which contains:
* a class HelperAdmin,
* menuItem() method and
* a class static array $arrMenuItems.
A content of this ARRAY returned by calling HelperAdmin::menuItem().
We want get data from the HelperAdmin class twice:
1. While generating a menu in admin.php;
2. As part of content which we get with variable $content putting it at this file.
$content in turn is generated in another file:
/modules/admin/views/generator/index.php
So as you can see, our page compounds itself from the template file /modules/admin/views/layouts/admin.php and data ($content) getting from /modules/admin/views/generator/index.php.
First I get data for menu:
HelperAdmin::menuItem();
$items=HelperAdmin::$arrMenuItems;
$this->widget(....
'items'=>$items,
...),
));
That's OK. Notice that after this a static array $arrMenuItems already is generated in HelperAdmin.
Next I'm trying to get the same data ($arrMenuItems generated earlier) in file /modules/admin/views/generator/index.php to place it as $content:
$items=HelperAdmin::$arrMenuItems
And here I can't get it as described above.
Well, I hope it made a situation more clear (?).