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 %}
Related
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
I am trying to figure out how I can give my data output in the blade file, the Laravel look;
like $data->name
But I can't get the output to be casted as an object. I think I have to make an array of the data before I can loop it proper in a foreach but this doesn't feel like the right way.
I am relatively new to Laravel and I want to do this the nice way, can someone point me in the right direction? Thanks in advance
Controller:
$data = collect($this->api->organization->index())->toArray();
return View::make('pages.organization.index', array('data' => $data[0]));
View:
#foreach($data as ((object)$organization))
{{ $organization->name }}
#endforeach
I know this will not work, but I think it illustrates my question a little bit.
EDIT
What I didn't realize is that $data = collect($this->api->organization->index()); is returning an array with all the data arrays inside because I didn't name it in my return like this:
return (object)['all' => $data];
After adding all I could reference the code inside my view like I wanted to. I know this is not a very detailed answer, if you run into the same problem message me I'll edit the answer.
Object:
$data = collect($this->api->organization->index());
#foreach($data as $organization))
{{ $organization->name }}
#endforeach
Array:
$data = collect($this->api->organization->index())->toArray();
#foreach($data as $organization))
{{ $organization['name'] }}
#endforeach
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
i'm trying to make a loop in php while using twig and inside this loop,
i am creating a parameter which contains the record from the database query.
The problem is that when I use the parameter in my HTML file, it only return 1 record from the while loop, even if there are 3 or 4 or even more..
This is the php code I have:
public function getWidgetsByName($name)
{
global $params;
$get = $this->db->query("SELECT * FROM profile_items
WHERE category = 'widget'
AND username = '". $name ."'");
if($get)
{
while($key = $get->fetch())
{
$params["profile_widget_name"] = $key['name'];
}
}
}
And this is the HTML parameter in my HTML twig rendered file:
{{ profile_widget_name }}
The paremeters just get rendered how they are supposed to be rendered:
echo $twig->render('app/views/'. $_REQUEST['p'] .'.html', $params);
And yes the $params variable is an array, in the config it file it first gets used as $params = array("..." => "..."); and I add things to this array by doing $params["..."] = "...";
So, I hope someone can help me.
Thanks in advance,
Best Regards.
At the moment, the value of $params["profile_widget_name"] is just one string. Every time you go through the while loop, you overwrite the previous value of the key with the current value.
So when you pass $params to Twig, the value of profile_widget_name is the value of name in the last row of the database to be selected.
I think what you want instead is for the value of profile_widget_name to be an array. Then every time you go through the loop, the current value of name is added to the array, instead of overwriting it.
You do this by doing something like:
$params["profile_widget_names"][] = $key['name'];
Now in your Twig template, you'll need to do something like:
{% for profile_widget_name in profile_widget_names %}
{{ profile_widget_name }}
{% endfor %}
Using Multiple Parameters
If you want multiple parameters to be on there, you can do this:
$params["profile_widgets"][] = [
'pos_x' => $key['pos_x'],
'name' => $key['name'],
];
And in Twig:
{% for profile_widget in profile_widgets %}
Name: {{ profile_widget.name }}
Pos X: {{ profile_widget.pos_x }}
{% endfor %}
I'm trying to display data from database.
This is my routing:
pages:
pattern: /pages/{id}
defaults:
_controller: DprocMainBundle:Index:show
This is the method for that route:
public function showAction($id)
{
$page = $this->getDoctrine()
->getRepository('DprocMainBundle:Pages')
->find($id);
if (!$page) {
throw $this->createNotFoundException('No product found for id '.$id);
}
return $this->render('DprocMainBundle:Dproc:single.html.twig',array('pages' => $page));
}
print_r($page) displays:
Dproc\MainBundle\Entity\Pages Object
(
[Id:protected] => 1
[page_title:protected] => A Foo Bar
[page_content:protected] => Test content for page
[page_category:protected] => 3dsmax
)
In single.html.twig im trying to display that information:
{% for page in pages %}
{{ page.page_title }}
{% endfor %}
It shows nothing, what i'm doing wrong?
The method find() will just return a single result, not an array. If you did findBy(array('id'=>$id)) then you would get an array back with one result. Alternatively you could just not loop through in your template because there's no need when you have only one result. Just change your variable name to page and use {{ page.page_title }}
You used two differents entity.. one is in getRepository('DprocMainBundle:Pages') and other is in render('DprocMainBundle:Dproc:single.html.twig',array('pages' => $page)). You should put there the same entity i.e DprocMainBundle:Pages . I hope this you success.
Try it without the for loop. Because you have post data from the database, you can try this:
{{ pages.page_title }}