Retrieving a cast array in Laravel 5.5? - php

Hi I think I'm misunderstanding casts? Basically I am trying to display an already stored array back to my view and its not working, i have already stored the arrays and im just trying to retrieve them into plain text
I have a table:
> Games
>>id |
>>name |
>>mode
MyController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Input;
use Illuminate\Http\Request;
use App\Game;
use App\Mode;
class MyController extends Controller
{
public function gameView($id)
{
$game = Game::find($id);
return view('admin.game.view', ['game' => $game]);
}
}
My model Game.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Game extends Model
{
protected $casts = [
'mode' => 'array',
];
public function modes()
{
return $this->hasMany(Mode::class);
}
}
Finally my View view.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">View User's Teams & Manage</div>
<div class="panel-body">
<ul>
<li>{{$game->name}}</li>
<li>{{$game->mode}}</li>
<li>{{$game->size}}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
#endsection

There are so many ways of printing an array, however, the simplest method is using the foreach loop.
#foreach ($game->mode as $mode)
<span>{{ $mode }}</span>
#endforeach
Or you can do something like {{ implode(", ", $game->mode) }} depending on your preference.

You are displaying the array like a string and there is the problem so you need to loop for the array of mode.
#for($i=0;$i<count($game->mode);$i++){ // here you print your result }

Related

count(): Argument #1 ($value) must be of type Countable|array, null given ORM

PostsController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
use App\Models\Post;
class PostsController extends Controller
{
public function index()
{
$posts = Post::orderBy('created_at','desc');
return view('pages.index')->with('posts', $posts);
}
index.blade.php
<h1>Posts</h1>
#if(count($posts) > 0)
#foreach($posts as $post)
<div class="well">
<div class="row">
<div class="col-md-4 col-sm-4">
<img style="width:100%" src="/storage/cover_images/{{$post->cover_image}}">
</div>
<div class="col-md-8 col-sm-8">
<h3>{{$post->title}}</h3>
<small>Written on {{$post->created_at}} by {{$post->user->name}}</small>
</div>
</div>
</div>
#endforeach
#else
<p>No posts found</p>
#endif
when i go to website it pops up error and i do not know what should i do. Actually there is one question with this title which i have but actually it did not help me.
Laravel provide much better solution for this kind of scenario, use forelse
#forelse ($posts as $post)
...
#empty
<p>No posts found</p>
#endforelse
Please the blade document.
You forget to put get() to your query
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
use App\Models\Post;
class PostsController extends Controller
{
public function index()
{
$posts = Post::orderBy('created_at','desc')->get();
return view('pages.index')->with('posts', $posts);
}
Check the offical docs for using Count()
https://www.php.net/manual/en/function.count.php
Can you do a "dump" of your "$posts" and see what do you have?
Before using "count" function, i recommend to check the type of your "$posts" or doing something like:
$posts = Post::orderBy('created_at','desc') ?? [];
Or make it more simple by adding a return type on your "orderBy" function like
public static function orderBy(...) : Array {}
Another related issue which can help: https://stackoverflow.com/a/69055096/7186622

Livewire Laravel - TypeError: Cannot read property 'getAttributeNames' of null

I'm fetching data from Ajax after sending a form. There is a listener that is setting the attribute to my component.
What I'm trying to achieve is to display my results after having submitted the form.
In the component, the model has been well retrieved but when I would like to display it to my component, I get an error.
directive_manager.js:26 Uncaught (in promise) TypeError: Cannot read property 'getAttributeNames' of null
at _default.value (directive_manager.js:26)
at new _default (directive_manager.js:6)
at new DOMElement (dom_element.js:12)
at Function.value (dom.js:36)
at Component.get (index.js:56)
at Component.value (index.js:272)
at Component.value (index.js:246)
at Component.value (index.js:182)
at Component.value (index.js:158)
at Connection.value (index.js:30)
index.blade.php
<div id="results-products" class="results-products">
<livewire:charts-products>
</div>
....
<script>
...
var product= fetchData(url);
window.livewire.emit('set:product', product)
...
</script>
charts-products.blade.php
<div>
#isset($product)
#foreach ( $product->category as $category)
<div class="card">
<div class="card-header">
<h4>Product category</h4>
</div>
</div>
#endforeach
#endisset
</div>
ChartsProducts.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Product;
class ChartsProducts extends Component
{
public $products;
protected $listeners = [
'set:product' => 'setProduct'
];
public function render()
{
return view('livewire.charts-products');
}
public function setProduct($product)
{
$this->product= Product::find($product);
//I have checked and the assigned variable is ok
}
}
The products is a model and has a relationship Category.
Is there something that I missed ?
This has to do with the way the dom-differ inside Livewire behaves. Try adding a key to the loop item
<div>
#isset($product)
#foreach ($product->category as $category)
<div class="card" wire:key="{{ $loop->index }}">
<div class="card-header">
<h4>Product category</h4>
</div>
</div>
#endforeach
#endisset
</div>
See the troubleshooting in the docs https://laravel-livewire.com/docs/troubleshooting
Also, change your public property from $products to $product

Laravel - Getting all records not just the first and putting together?

I have tried asking this question to everyone but nobody can see why I am trying to do it or why its not working but I will try my best to explain it properly this time.
I have a simple government page on my website that shows 3 panels in bootstrap with Higher Government, Senior Ministers and Junior Ministers. Inside each of them panels it shows a list of accounts assigned to that government rank.
Here is my government.blade.php:
#include('frontend.header')
<div class="col-md-12" style="padding-bottom:24px;">
<ul class="nav navtab nav-tabs" id="myTab" style="border-bottom:none;border-radius:1px;">
<li style="padding-right:13px;" class="active"><a style="" data-target="#higher_government_team" data-toggle="tab"><i class="fa fa-diamond" aria-hidden="true"></i> The Monarch/PM</a></li>
<li style="padding-right:13px;"><a style="" data-target="#senior_government_team" data-toggle="tab"><i class="fa fa-university"></i> Seniors</a></li>
<li style="padding-right:13px;"><a style="" data-target="#junior_government_team" data-toggle="tab"><i class="fa fa-university"></i> Juniors</a></li>
</ul>
</div>
<div class="col-md-8">
<div class="tab-content">
<div class="tab-pane active" id="higher_government_team">
<div class="panel panel-info">
<div class="panel panel-body">
higher gov here
</div>
</div>
</div>
<div class="tab-pane" id="senior_government_team">
<div class="panel panel-info">
<div class="panel panel-body">
senior gov here
</div>
</div>
</div>
<div class="tab-pane" id="junior_government_team">
<div class="panel panel-info">
<div class="panel panel-body">
#foreach ($juniorGovernment as $governmentMember)
{{ $governmentMember->user_id }}<br>
#endforeach
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
</div>
</div>
#include('frontend.footer')
Here is my controller for displaying the page:
<?php
namespace App\Http\Controllers\Frontend\User;
use Auth;
use Cache;
use Illuminate\Http\Request;
use App\Database\Website\User\Roleplay;
use App\Database\Website\Roleplay\GovernmentRole;
use App\Database\Website\Roleplay\Life\LifeEvents;
class GovernmentController
{
public function getView()
{
$higherGovernment = Cache::remember('government.higher_government', 1, function() {
return GovernmentRole::where('government_type', 'higher_government')->first()->stats;
});
$seniorGovernment = Cache::remember('government.senior_government', 1, function() {
return GovernmentRole::where('government_type', 'senior_ministers')->first()->stats;
});
$juniorGovernment = Cache::remember('government.junior_government', 1, function() {
return GovernmentRole::where('government_type', 'junior_ministers')->first()->stats;
});
return view('frontend.community.government', compact('juniorGovernment', 'seniorGovernment', 'higherGovernment', 'royalty'));
}
}
Now as you can see, I only select the first record where government_type matches. But the issue is I have multiple government roles with that government type and I want to get all the account stats for all records with that government type. I have looked at others suggestions and none of them work, either throwing an error or don't do what I want to do.
Now, I have modals for each Roleplay and GovernmentRoles, I have posted them both below.
GovernmentRole:
namespace App\Database\Website\Roleplay;
use Eloquent;
class GovernmentRole extends Eloquent
{
protected $primaryKey = 'id';
protected $table = 'srp_government_roles';
public $timestamps = false;
protected $fillable = [];
public function stats(){
return $this->hasMany('App\Database\Website\User\Roleplay', 'government_id');
}
}
Roleplay:
use Eloquent;
class Roleplay extends Eloquent
{
protected $primaryKey = 'id';
protected $table = 'srp_user_statistics';
public $timestamps = false;
protected $fillable = [];
public function user()
{
return $this->belongsTo('App\Database\Website\User\Player', 'user_id', 'id');
}
public function government_role()
{
return $this->belongsTo('App\Database\Website\Roleplay\GovernmentRole', 'government_id');
}
}
So what I am trying to achieve is not just grabbing all the Roleplay instances for the FIRST government role record in the database it finds but putting together ALL roleplay instances for ALL records that match government_type either higher_government, senior_ministers, or junior_ministers.
If I understand what you are asking, can you not do something like fetching the stats on your loop through in blade? For example (I removed the cache, its adding complexity to the question/answer without any benefit):
// controller
$higherGovernment = GovernmentRole::where('government_type', 'higher_government')->get();
// blade
#foreach($higherGovernment as $g)
{{ $g->id }}
{{ $g->name }}
#foreach($g->stats as $stat)
{{ $stat->id }}
{{ $stat->something }}
#endforeach
#endforeach

Use custom class in Laravel 5

In app/Library I have a file called Helpers.php
<?php
namespace App\Library\Helpers;
class Helpers {
public function truncate($text) {
if (strlen($text) > 200) {
preg_replace('/\s+?(\S+)?$/', '', substr($text, 0, 201));
}
return $text;
}
}
In one of my views, I want to use the class:
#foreach($data['articles'] as $article)
<div class="container">
<div class="article">
<h1>{{ $article->title }}</h1>
<p>
<?php
$helpers = new \App\Library\Helpers;
echo $helpers->truncate($article->body);
?>
</p>
</div>
</div>
#endforeach
I get this error:
Class 'App\Library\Helpers' not found
You are trying to use a namespace not a class, your class is actually App\Library\Helpers\Helpers. Using blade you can use the inject method to get your class in a view.
#inject('helpers', 'App\Library\Helpers\Helpers')
#foreach($data['articles'] as $article)
<div class="container">
<div class="article">
<h1>{{ $article->title }}</h1>
<p>{{ $helpers->truncate($article->body) }}</p>
</div>
</div>
#endforeach
Using inject creates a new variable of the name passed as the first argument with a value of the class passed in as the second argument. Your helpers are now available in the view.
<?php
$helpers = new App\Library\Helpers\Helpers;
echo $helpers->truncate($article->body);
?>
Or fix the namespace name.
namespace App\Library;

Errors when trying to display relational data

I've been following the Laracasts Project-Flyer and have come to an end of the current videos in the series. I have decided to go off and expand on the app myself.
I'm trying to display the latest 3 flyers ( or in my case, classifieds) on the home page, along with an image.
I have been able to pull the last 3 entries and display them fine on the home page, but I've been trying to follow the same approach of displaying the images on the classified page, for the images for each classified on the home page.
Here is my code I have used.
Classified Model snippet:
<?php
namespace App;
use DB;
use Illuminate\Database\Eloquent\Model;
class classified extends Model
{
...
public function photos()
{
return $this->hasMany('App\classified_photo');
}
...
public static function getLatestClassifeds()
{
return DB::table('classifieds')
->select('ad_title','description')
->orderBy('created_at','desc')
->take(3)
->get();
}
...
Home Page Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\classifiedRequest;
use App\Http\Controllers\Controller;
use App\classified;
use App\classified_photo;
class HomeController extends Controller
{
public function show()
{
$classifieds = classified::getLatestClassifeds();
return view('pages.home', compact('classifieds'));
}
}
Home View:
#foreach($classifieds as $classified)
<div class="col-xs-6 col-sm-4">
<div class="col-xs-12">
#if($classified->photos)
#foreach($classified->photos as $photo)
<img src="/{{$photo->thumbnail_path}}" class="img-responsive">
#endforeach
#endif
</div>
<div class="col-xs-12">
<div class="classified-desc">
<h2>{{$classified->ad_title}}</h2>
<p>{{$classified->description}}</p>
</div>
</div>
<div class="col-xs-12">
<div class="btn-group btn-group-justified" role="group" aria-label="...">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default">Left</button>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-default">Right</button>
</div>
</div>
</div>
</div>
#endforeach
This code returns this error when I try to view the home page:
Undefined property: stdClass::$photos (View: /var/www/html/barrys-bikes.dev/resources/views/pages/home.blade.php)
As I say, displaying the 3 classifieds works fine, its just this issue with trying to then pull an image for each one.
The problems is, because you using DB::table()... instead of Eloquent ORM. Do something like this:
public static function getLatestClassifeds()
{
return self::orderBy('created_at','desc')
->take(3)->get(['ad_title', 'description']);
}

Categories