error of foreach with empty array - php

I'm working in Laravel 5 using Blade as motor of templates. I'm passing an array from the controller to the view, and I noticed that when I loop on it using the foreach clausule and the array is empty it gives error, exactly this:
Invalid argument supplied for foreach()
I had the same error in the controller and I fix it temporaly making:
if(count($student)!=0)
I said temporaly because I don't think it this the best way to do it.
The code in the controller is:
foreach($students as $student){
if(count($student->contracts)!=0)
foreach($student->contracts as $contract){
//something
}//end foreach
}//end foreach
I made some operations over the arrays, and then I send them to the view:
return view('myview')->with(['students'=>$students]);
The array is passing to the view correctly. I said is the foreach, beacause earlier I had the database full of registers and it worked fine, but now I have some students that doesn't have contracts and then I got that error. But, in the view I have the same error. So, it's normal? how could I fix it in a better way? why when the array is empty the foreach clausule gives that error?

PHP will not return that warning if the array contained at $student->contracts is empty. It will return it if it is of an invalid type (i.e. not an array).
Rather than checking the count() of $student->contracts, you'd be better to check if it's actually an array, as follows:
foreach($students as $student)
{
// Make sure that $student->contracts is actually an array (to bypass errors):
if( is_array($student->contracts) )
{
// Now loop through it:
foreach( $student->contracts as $contract)
{
// Do something here
}
}
}

Try this
$people = [
"Person A", "Person B", "Person C"
];
return view ('pages', compact('people'));
and loop through it like this:
#if (count($people))
<h3>People:</h3>
<ul>
#foreach($people as $person)
<li>{{ $person }}</li>
#endforeach
</ul>
#endif

Related

Query field added but not visible in template

In my Symfony project I try to append new array key-value pair into the result I am rendering to twig template file.
It has some odd behaviour.
$posts = $this->entityManager->getRepository(Post::class)->getPage($listType, $page, $pageSize);
foreach ($posts['data'] as $post) {
$post['destinationName'] = $this->destinationService->getDestinationName($posts['data']);
}
return $this->render('posts.html.twig', [
'posts' => $posts['data'],
]);
Trough this getPage() method in my controller I get paginated list of my data. Which is working. Than in the foreach() I am appending new key-value pair to that array.
When dumping $posts I get: IMAGE
When dumping $post from foreach, this is the output I get: IMAGE As you can see, the last pair, destinationName is added.
Then when dumping the same result in my twig template I get: IMAGE
As you can see, when template is rendered, it disappears.
My question is, that maybe it's overwritten? But I can not see why. Do I maybe need to append that filed in my query builder? But as I am adding the field after result is rendered, I suppose that should not be the case..
Any hints?
Maybe getDestinationName() will show something:
public function getDestinationName($posts)
{
foreach ($posts as $postsData) {
foreach ($postsData as $post) {
$destinationName = $this->getDestinationDetails(
$post->getDestinationId(),
$post->getAccountTokenId()
);
return $destinationName['full_name'];
}
}
}
It's not a good practice to mixe array with object and then add other stuff.
The best thing you could do is this :
$posts = $this->entityManager->getRepository(Post::class)->getPage($listType, $page, $pageSize);
$destinationNames = [];
foreach ($posts['data'] as $post) {
$destinationNames[$post->getPostId()] = $this->destinationService->getDestinationName($posts['data']);
}
return $this->render('posts.html.twig', [
'posts' => $posts['data'],
'destinationNames' => $destinationNames,
]);
I suppose here that $post->getPostId() is your unique identifier, if not, replace by the right identifier
And in your template you could do something like :
{% for post in posts %}
// do your stuff
{{ destinationNames[post.id] }}
{% endfor %}

how to pass data to a view without using if statement and foreach in the show file?

when I watched youtube Laravel From Scratch [Part 6] - Fetching Data With Eloquent , and I saw him pass data to view without using if statement and foreach, I has been tried but not working
public function show(todo $todo)
{
$todo=todo::find($todo);
return view('demo')->with('todo',$todo);
}
my view without if statement and foreach
#extends('layouts.app')
#section('content')
{{$todo->note}}
#endsection
my view when using if statement and foreach
#extends('layouts.app')
#section('content')
#if (count($todo) > 0)
#foreach ($todo as $item)
{{$item->note}}
#endforeach
#endif
#endsection
and I recievied an error
Property [note] does not exist on this collection instance
https://www.youtube.com/watch?v=emyIlJPxZr4&list=PLillGF-RfqbYhQsN5WMXy6VsDMKGadrJ-&index=6
The reason the property doesn't exist is because the result is a collection instead of an array (found in the op comments)
So you're trying to get note from an collection that looks like this:
[
{
"id":1,
"note":"to do one",
"created_at":"2020-04-12 08:25:00",
"updated_at":"2020-04-13 07:20:54",
"description":"description for todo one"
}
]
When you call $todo->note you're searching this line:
[
{ # <-- You're searching this line
"id":1,
"note":"to do one",
"created_at":"2020-04-12 08:25:00",
"updated_at":"2020-04-13 07:20:54",
"description":"description for todo one"
}
]
So your code is returning a collection instead of an array. An array would look like this:
{ # <-- Starts with open curly bracket instead of open square bracket
"id":1,
"note":"to do one",
"created_at":"2020-04-12 08:25:00",
"updated_at":"2020-04-13 07:20:54",
"description":"description for todo one"
}
You need to figure out why it's sending a collection.
From the look of your code, I find a potential issue with this:
public function show(todo $todo) # <- What is 'todo $todo'?
{
$todo=todo::find($todo);
return view('demo')->with('todo',$todo);
}
What is todo $todo, are you calling the show function somewhere? By default Laravel sends that ID via the web route. So try updating it to this:
public function show($id) #<-- change this to '$id'
{
$todo = Todo::find($id); #<-- Change this to '$id'
return view('demo')->with('todo',$todo);
}
Let me know if that resolves it.
Edit: And you really need to fix your capitalization.
$todo=todo::find($todo)->first();

Empty array don't appear as empty in Laravel blade

Right now I'm trying to check when the view receives an empty array.
#if(! empty($array))
// Section content goes here...
#foreach($array as $value)
// All table data goes here...
#endforeach
#endif
The code as it is above seems to still run when the $array is empty and causes an exception.
When I try to dump the array with {{ dd($array) }} I get $array = [].
Sounds like you might be having a collection. You could simply do count($array) to check amount of records in the array. It would look something like this:
#if(count($array))
// Section content goes here...
#foreach($array as $value)
// All table data goes here...
#endforeach
#endif
The section should now be hidden. If you wish to only skip the foreach when there is nothing in the array you could do this:
// Section content goes here...
#forelse($array as $value)
// All table data goes here...
#empty
// Optional message if it's empty
#endforelse
Which would output the section content and check if the array has any values before it foreach it.
You can read more about loops within blade files in the Laravel documentation.
Is it possible your array is a collection?
Try using a #forelse, this will check if the array or collection is empty and display another block instead. For example:
#forelse($array as $value)
{{ $value }}
#empty
array is empty
#endforelse

how to if else to show something else laravel

my view page:
#if(empty($data))
<p>No response have been attached to this entities.</p>
#else
<p>By default, it will respond with the predefined phrases. Use the form below to customize responses.</p>
#endif
controller:
public function queries($companyID, $entityType, $entityValue)
{
$data = [];
$details = DiraQuestion::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach ($details AS $datum)
{
if (!isset($data[$datum->intent])) $data[$datum->intent] = ['question' => [], 'answer' => []];
$data[$datum->intent]['question'][$datum->queries] = $datum->id;
}
$detailsAns = DiraResponses::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach ($detailsAns AS $datum)
{
if (!isset($data[$datum->intent])) $data[$datum->intent] = ['question' => [], 'answer' => []];
$data[$datum->intent]['answer'][$datum->reply] = $datum->id;
}
ksort($data);
return view('AltHr.Chatbot.queries', compact('data','entityType','entityValue','companyID'));
}
I made the controller and view shown above, but I can't seem to figure out what the problem is when there is no data it still shows like this:
I am trying to have it show the data but when there isn't data then for it to show something else.
I have two examples of with and without data when I dd();
first with data:
second without data:
so the one without data should shows something else like an error message.
$data is not empty in both cases, you need to be checking the answer index:
#if(empty($data['answer']))
<p>No response have been attached to this entities.</p>
#else
<p>By default, it will respond with the predefined phrases. Use the form below to customize responses.</p>
#endif
edit
You've also got an empty string index wrapping both answer and question so
#if(empty($data['']['answer']))
because you use empty() function to check data,but in controller $data is array, so It always not empty.
You can change empty() function to count() function. If $data is empty or null, it will be equal zero.
#if(count($data)==0)
<p>No response have been attached to this entities.</p>
#else
<p>By default, it will respond with the predefined phrases. Use the form below to customize responses.</p>
#endif

Blade laravel variable value type?

I'm new to laravel
Just being curious,
Suppose I make an array in a view page
myView.blade.php
Suppose:
$array = [
1, 2, 3
];
in the same page, I want to loop it with "blade" foreach
suppose:
#foreach($array as $value)
<span id="{{$value}}">{{$value}}</span>
#endforeach
but, I get an error like this.
ErrorException in 1ed42d9dadecab7c54e086f573c4cbad6576e7c3.php line 63:
Trying to get property of non-object...
what's happened? what type of variable actually blade converts?
Any question will highly appreciated! :)
First of all, it's better if you just pass the data to your view files from controller.
But, if you still want to do that, and you are using Laravel 5.3, you can do it like this:
#php
$array = [
1, 2, 3
]
#endphp
and then loop it:
#foreach($array as $value)
<span id="{{$value}}">{{$value}}</span>
#endforeach
Make, sure that you declare the $array array before the loop.
Have a look at the Service Injection and View Composers on Larave's documentation aswell.
Actually, I don't know what do you want? But recommendly, you should init your array at controller, through it to view and foreach.
In controller,
return view('your view path', ['array' => $array]);
In blade
#foreach($array as $value)
<span id="{{$value}}">{{$value}}</span>
#endforeach
Hope it could help, thanks.

Categories