For sure it's an understanding issue on my part. I'm just trying to create a collection in which the elements can be output.
Example:
So I want to be able to execute:
$collection=collect([
'index1' => 'data1',
'index2' => 'data2',
'index3' => 'data3',
]);
$row=$collection->first();
dd($row->index1);
Or similar.. But I get the error
trying to get property of a non object.
It's an understanding issue about Laravel collections, I've read the Laravel documentation which goes from basic usage, to API reference. I cannot find the information on how to produce this basic static collection.
Can someone help?
$row=$collection->first(); points to the value data1, not an object/array.
To get the expected behavior try the code below, it wraps each in individual arrays.
$collection=collect([
['index1' => 'data1'],
['index2' => 'data2'],
['index3' => 'data3'],
]);
$row=$collection->first();
dd($row->index1);
As Laravel collections implement ArrayAccess you can simply access collection items as you do with an array
$value = $collection['index1'];
or you can use the get method on collections
$value = $collection->get('index1');
Thanks for your answers, I see the $collection['index1']; format works.
It's not exactly what I wanted, let me explain why. I know there's probably a better way of doing it although, for the sake of this particular coding requirement I'd like to know the answer to this.
I'm building a CRUD blade form.
On my blade I'll have 'field1' with initial output of $dbcollection->field1
Now of course if the database returns a null (create required) this output will fail. So what I'm trying to do here is pass blade a NULL-filled collection it understands so at least it doesn't complain about non instance of an object and avoiding #if statements on the blade form to account for differences in coding format.
I believe this is what you are looking for:
Controller:
$collection=collect([
'index1' => 'data1',
'index2' => 'data2',
'index3' => 'data3',
]);
$row = $collection->first();
view:
<input type="text" value="{{ ($row->index1 ? $row->index1 : '') }}" >
.
.
.
.
Related
I have the following line to get an array of collections.
$tags = Tag::all()->map->only(['id', 'name']);
Which produces the following data.
[{"id":1,"name":"tag 2"},{"id":2,"name":"tag 3"},{"id":3,"name":"tag-44"},{"id":4,"name":"biyoloji"}]
My objective is to rename the key names inside the collections as follows.
[{"value":1,"text":"tag 2"},{"value":2,"text":"tag 3"},{"value":3,"text":"tag-44"},{"value":4,"text":"biyoloji"}]
Basically, I want to rename "key" to "value" and "name" to "text." I tried the pluck() function, get() function, mapping but couldn't get it to work. Most probably, iterating over it with foreach and toArray() would do the trick, but I'm looking for the proper way to do it. My environment is Laravel 8 with PHP 7.4
The best way I can propose:
$tags = Tag::query()->get(['id', 'name'])
->map(function($tag){
return [
'value' => $tag->id,
'text' => $tag->name,
];
})
->toArray();
Pay attention to get(['id', 'name]) invoking. Passing required fields to get method helps improving query performance. Specially if there are lots of unused columns in the table.
You can do this via your query more efficiently
$tags = Tag::get(['id as value', 'name as text']);
I have a line of code similar to the following:
Sport::pluck('id', 'name)
I am dealing with frontend JavaScript that expects a list in this format:
var list = [
{ text: 'Football', value: 1 },
{ text: 'Basketball', value: 2 },
{ text: 'Volleyball', value: 3 }
...
]
I am trying to figure out how I can somehow transform the id and name values that I pluck from my model to a format similar to the Javascript list.
If that's unclear, I am looking to end up with an associative array that contains two keys: text and value, where text represents the name field on my model, and where value represents the id of the model - I hope this makes sense.
How would I approach this?
I initially tried something like this (without checking the documentation)
Sport::pluck(["id" => "value", "name" => "text]);
But that isn't how you do it, which is quite clear now. I've also tried some map-related snippet, which I cannot seem to Ctrl-z to.
Any suggestions?
Another method is to use map->only():
Sport::all()->map->only('id', 'name');
The purpose of pluck is not what you intend to do,
Please have a look at below examples,
Sport::selectRaw("id as value, name as text")->pluck("text","value");
// ['1' => 'Football', '2'=>'BasketBall','3'=>'Volleyball',...]
Syntax
$plucked = $collection->pluck('name', 'product_id');
// ['prod-100' => 'Desk', 'prod-200' => 'Chair']
Please see the documentation.
Your output is possible using simple code.
Sport::selectRaw('id as value, name as text')->get();
You could use map.(https://laravel.com/docs/5.8/collections#method-map)
$mapped = Sport::all()->map(function($item, $index) {
return [
"id" => $item["id"],
"name" => $item["text"]
];
});
This is the easiest way. Actually Laravel offers a better way for it. You can use api resources to transform your data from eloquent for the frontend:
https://laravel.com/docs/5.8/eloquent-resources
Try with toArray function:
Sport::pluck('id', 'name)->toArray();
Then you can return your result with json_encode php function;
I am having an issue - well because the value I am trying to pull from the DB does not exist yet.
Is there away that I check if its isset?
Is there any better way that I can get my value from the db to save on double code?
Controller:
$siteSocialFacebook = socialSettings::where('socialName','=','facebook')->get();
$siteFacebook = $siteSocialFacebook[0]['socialLink'];
Blade:
value="{{ old('facebook', #$siteFacebook)}}"
If you will only ever expect one result, use first() instead of get() and skip the array. You can pass it into the Blade template like this:
return view('blade', [
'siteFacebook' => $siteSocialFacebook['socialLink'] ?: null,
]);
This will prevent any issues with undefined parameters.
Edit: I just realized you're treating models as arrays. You can do this too:
return view('blade', [
'siteFacebook' => $siteSocialFacebook->socialLink,
]);
That handles it for you.
Say I have an array in PHP that looks like so:
$values = Array(
'0' => 'value1',
'1' => 'value2',
'2' => 'value3'
)
I'd like to iterate through the array using Mustache but I'd like the associated value. This is what I'm hoping to do:
{{#values}}
{{the current value}}
{{/values}}
I hope there returned result would be:
value1
value2
value3
I've been getting around this by changing my structure to:
$values = Array(
'0' => array('value=' =>'value1'),
'0' => array('value=' =>'value2'),
'0' => array('value=' =>'value3'),
)
And call {{valule}} inside the Mustache iterator.
Should I be doing this a completely different way? I'm using a SplFixedArray in PHP and I'd like to iterate through the values using this method...
Thanks!
The implicit Iterator is the way to go for simple data. If your data is more complex then PHPs ArrayIterator does the job well.
Here is an example that I have working. Hope it is useful for somebody else.
$simple_data = array('value1','value2','value3');
$complex_data = array(array('id'=>'1','name'=>'Jane'),array('id'=>'2','name'=>'Fred') );
$template_data['simple'] = $simple_data;
$template_data['complex'] = new ArrayIterator( $complex_data );
$mustache->render('template_name', $template_data );
And in the template you could have
{{#simple}}
{{.}}<br />
{{/simple}}
{{#complex}}
<p>{{ id }} <strong>{{ name }}</strong></p>
{{/complex}}
You can use the implicit iterator feature of mustache for this:
https://github.com/bobthecow/mustache.php/tree/master/examples/implicit_iterator
{{#values}}
{{.}}
{{/values}}
Your original array probably needs numeric keys and now string though. It might work that way, but I haven't tested it.
I was working on a super old php framework, which was using smarty like syntax but double curly braces, kept me hanging for quite sometime, so the following made the loop run for me :) maybe it will help you too.
{{ #each link in bluelinks }}
<p><strong>{{ link }}</strong></p>
{{/each}}
I have created a form in which i embed another form. My question is about this embedded form - I'm using a sfWidgetFormDoctrineChoice widget with option multiple set to true. The code for this embedded form's configure method:
public function configure()
{
unset($this['prerequisite_id']);
$this->setWidget('prerequisite_id', new sfWidgetFormDoctrineChoice(array(
'model' => 'Stage',
'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
'multiple' => true
)));
$this->setValidator('prerequisite_id', new sfValidatorDoctrineChoice(array(
'model' => 'Stage',
'multiple' => true,
'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
'column' => 'id'
)));
}
I unset the prerequisite_id field because it is included in the base form, but I want it to be a multiple select.
Now, when I added the validator, everything seems to work (it passes the validation), but it seems like it has problems saving the records if there is more than one selection sent.
I get this PHP warning after submitting the form:
Warning: strlen() expects parameter 1 to be string, array given in
D:\Development\www\flow_dms\lib\vendor\symfony\lib\plugins\sfDoctrinePlugin\lib\database\sfDoctrineConnectionProfiler.class.php
on line 198
and more - I know, why - in symfony's debug mode I can see the following in the stack trace:
at Doctrine_Connection->exec('INSERT INTO stage_has_prerequisites
(prerequisite_id, stage_id) VALUES (?, ?)', array(array('12', '79'),
'103'))
So, what Symfony does is send to Doctrine an array of choices - and as I see in the debug sql query, Doctrine cannot render the query correctly.
Any ideas how to fix that? I would need to have two queries generated for two choices:
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (12, 103);
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (79, 103);
stage_id is always the same (I mean, it's set outside this form by the form in which it is embedded).
I have spend 4 hours on the problem already, so maybe someone is able to provide some help.
Well, I seem to have found a solution (albeit not the best one, I guess). Hopefully it'll be helpful to somebody.
Finally, after much thinking, I have concluded that if the problem comes from the Doctrine_Record not being able to save the record if it encounters an array instead of a single value, then the easiest solution would be to overwrite the save() method of the Doctrine_Record. And that's what I did:
class StageHasPrerequisites extends BaseStageHasPrerequisites
{
public function save(Doctrine_Connection $conn = null)
{
if( is_array( $this->getPrerequisiteId() ) )
{
foreach( $this->getPrerequisiteId() as $prerequisite_id )
{
$obj = new StageHasPrerequisites();
$obj->setPrerequisiteId( $prerequisite_id );
$obj->setStageId( $this->getStageId() );
$obj->save();
}
}
else
{
parent::save($conn);
}
}
(...)
}
So now if it encounters an array instead of a single value, it just creates a temporary object and saves it for each of this array's values.
Not an elegant solution, definitely, but it works (keep in mind that it is written for the specific structure of the data and it's just the effect of my methodology, namely See What's Wrong In The Debug Mode And Then Try To Correct It Any Way Possible).