Yii2 kartik depend dropdown doesnt load next drop down list - yii2

I am using kartik DepDropdown widget. When I choose the region it must load all the cities from it in the particular dropdown (e.g. the one with id city_id).
In the chrome network tab I can see that the action returns the expected result json format of all the cities
{
"output": {
"40": "Велико Търново",
"41": "Горна Оряховица",
"42": "Елена",
"43": "Златарица",
"44": "Лясковец",
"45": "Павликени",
"46": "Полски Тръмбеш",
"47": "Свищов",
"48": "Стражица",
"49": "Сухиндол"
},
"selected": ""
}
But they doesn't load in the #city_id dropdown. My view looks like:
<div class="col-sm-6">
<?= $form->field($model, 'region_id')->dropDownList(Region::getAllRegions(), ['id' => 'region-dd', 'prompt'=> ' - ' . Yii::t('app', 'Region') . ' - ']); ?>
</div>
<div class="col-sm-6">
<?= $form->field($model, 'city_id')->widget(DepDrop::classname(), [
'options'=>[
'id'=>'city-id'
],
'pluginOptions'=>[
'allowClear' => true,
'depends' => ['region-dd'],
'url' => Url::to(['/system-information/load-cities'])
]
]); ?>
</div>
My controller:
public function actionLoadCities()
{
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$region_id = $parents[0];
$out = City::getAllCities($region_id);
echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
echo Json::encode(['output'=>'', 'selected'=>'']);
}
Thank you in advance!

You have to provide the name=>value pairs of the id and the text to be assigned for a single option, if you look into the DOCS you will see that you have to return the array like below
[
'out'=>[
['id'=>'<city-id>', 'name'=>'<city-name>'],
['id'=>'<city-id>', 'name'=>'<city-name>']
],
'selected'=>'<city-id>'
]
which means that the id will be provided with the index id and the text for the dropdown will be provided with the index name, and looking at the response you have provided your method getAllCities is returning the array like below
[
'id'=>'name',
'id'=>'name',
]
you didn't add the method City::getAllCities($region_id); which is returning the $out array but on the very basic level as per documentation it should look like below,
Note: Change the table and column names respectively, I assume you have the id and name columns for the cities, if you have any other column name for the city name like city_name then you must create the alias name for the city_name field in the query.
public function getAllCities($region_id){
$query = new \yii\db\Query;
$query->select('id, name')
->from('{{%city}}')
->where(['=', 'region_id', $region_id])
->limit(20);
$command = $query->createCommand();
return $command->queryAll();
}
This will return an array like below.
Array
(
[0] => Array
(
[id] => 40
[name] => Велико Търново
)
[1] => Array
(
[id] => 41
[name] => Горна Оряховица
)
[2] => Array
(
[id] => 42
[name] => Елена
)
[3] => Array
(
[id] => 43
[name] => Златарица
)
)
which will be encoded as JSON like below
[
{
"id": "40",
"name": "Велико Търново"
},
{
"id": "41",
"name": "Горна Оряховица"
},
{
"id": "42",
"name": "Елена"
},
{
"id": "43",
"name": "Златарица"
}
]
and eventually when encode by the line
echo Json::encode(['output'=>$out, 'selected'=>'']);
it will return
{
"output": [
{
"id": "40",
"name": "Велико Търново"
},
{
"id": "41",
"name": "Горна Оряховица"
},
{
"id": "42",
"name": "Елена"
},
{
"id": "43",
"name": "Златарица"
}
],
"selected": ""
}
Hope this helps.

Related

How to loop through a JSON object in Perl?

I'm trying to create an api using perl, the api is for a react native, when the user submits a form on the app I'll get the following object,
I'm new to perl and I'm lost trying to loop thro the object :/
{
checkboxes: [
{
id: "1",
fullname: "Name 1",
color: "red",
res: false
},
{
color: "green",
fullname: "Name 2",
id: "2",
res: false
},
{
color: "blue",
id: "3",
fullname: "Name 3",
res: false
}
]
}
my $data_decoded = decode_json($data);
I'm trying this loop, but it only prints the full object.
foreach $a (#data) {
print "value of a: $a\n";
}
You turned your JSON into a reference Perl data structure with decode_json (from somewhere, and Mojo::JSON is such a place):
use Mojo::JSON qw(decode_json);
my $data = ...;
my $data_decoded = decode_json($data);
Now you have to figure out how to access whatever you have in $data_decoded. You can look at its structure by dumping it
use Mojo::Util qw(dumper);
print dumper( $data_decoded );
You'll see that the Perl structure is the same as the JSON structure. You have a hash (JSON's Object) that has a checkboxes key that points to an array. The array elements are hashes.
Using Perl v5.24's postfix dereferencing notation, you get all of the array elements:
# uglier circumfix notation #{$data_decoded->{checkboxes}}
my #elements = $data_decoded->{checkboxes}->#*;
You might put that in a loop:
foreach my $hash ( $data_decoded->{checkboxes}->#* ) {
...
}
Now you get each hash element in $hash and you can do whatever you like with it. That part you haven't told us about yet. :)
The Perl Data Structures Cookbook (perldsc) has a lot of examples of the generation and iteration of various combinations of hash and array references.
You say that you want to do something when the value of the res key is true. In that case, you can use next to skip the items where res is false:
foreach my $hash ( $data_decoded->{checkboxes}->#* ) {
next unless $hash->{res};
say "I'm doing something when res is true";
}
Following demo code demonstrates looping through these particular data
use strict;
use warnings;
use feature 'say';
use JSON;
use Data::Dumper;
my $input = do { local $/; <DATA> };
my $data = from_json($input);
say Dumper($data);
for my $obj ( #{$data->{checkboxes}} ) {
say join(",\t", $obj->#{qw/id fullname color/});
}
__DATA__
{
"checkboxes": [
{
"id": "1",
"fullname": "Name 1",
"color": "red",
"res": false
},
{
"color": "green",
"fullname": "Name 2",
"id": "2",
"res": false
},
{
"color": "blue",
"id": "3",
"fullname": "Name 3",
"res": false
}
]
}
Output
$VAR1 = {
'checkboxes' => [
{
'res' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
'color' => 'red',
'fullname' => 'Name 1',
'id' => '1'
},
{
'fullname' => 'Name 2',
'color' => 'green',
'res' => $VAR1->{'checkboxes'}[0]{'res'},
'id' => '2'
},
{
'id' => '3',
'color' => 'blue',
'res' => $VAR1->{'checkboxes'}[0]{'res'},
'fullname' => 'Name 3'
}
]
};
1, Name 1, red
2, Name 2, green
3, Name 3, blue

How to pass an array into laravel json?

Here my simple code..
$country=['Bangladesh','Pakistan'];
$capital=['Dhaka','Islamabad'];
return response()->json([
'country'=>$country,
'roll'=>$roll,
]);
If i run the above code ,the output will be like below..
{
"country": [
"Bangladesh",
"Pakistan"
],
"roll": [
'Dhaka',
'Islamabad'
]
}
But I want that my expected output will be like ..
EDIT: Following JSON is invalid (2 same key country)
{
{
"country":"Bangladesh",
"capital":"Dhaka"
},
{
"country":"Pakistan",
"capital":"Islamabad"
},
}
try this
$countries = ['India', 'Bangladesh', 'Pakistan'];
$capital = ['Delhi', 'Dhaka', 'Islamabad'];
$response = [];
foreach ($countries as $key => $country) {
$response[$key] = [
'country' => $country,
'capital' => $capital[$key],
];
}
return response()->json($response);
it will return
[{
"country": "India",
"capital": "Delhi"
},
{
"country": "Bangladesh",
"capital": "Dhaka"
},
{
"country": "Pakistan",
"capital": "Islamabad"
}
]
Your expected output is wrong. You simply cant have 2 same keys (country) in output json. You should have country and capital encapsulated in separate {}.

Laravel Array & JSON Casting to Algolia

I am trying to send some data along to Algolia through the toSearchableArray. Any strings I have stored in my DB are sending along fine, but I hit a roadblock when trying to push nested JSON data along—the information is being sent as a string with characters escaped.
This is a sample of the nested object that I am storing in my table (MySQL with a JSON data type):
[
{
"id": 19,
"name": "Mathematics",
"short": "Math"
},
{
"id": 23,
"name": "Science",
"short": "Science"
},
{
"id": 14,
"name": "Health and Life Skills",
"short": "Health"
}
]
My model looks like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Resource extends Model
{
use Searchable;
protected $primaryKey = 'objectID';
public function toSearchableArray()
{
$data = $this->toArray();
$data['grades'] = explode(';', $data['grades']);
$data['units'] = explode(';', $data['units']);
return $data;
}
}
I get an output that looks like this:
array:22 [
"objectID" => 1
"name" => "Resource #1"
"slug" => "resource-1"
"write_up" => """
This is an example write up.
"""
"author" => "johnny"
"type_name" => "Lesson Plan"
"language" => "English"
"grades" => array:3 [
0 => "Kindergarten"
1 => "Grade 1"
2 => "Grade 4"
]
"subjects" => "[{"id": 19, "name": "Mathematics", "short": "Math"}, {"id": 23, "name": "Science", "short": "Science"}, {"id": 14, "name": "Health and Life Skills", "short": "Health"}]"
"units" => array:2 [
0 => "Unit A"
1 => "Unit B"
]
"main_image" => "https://dummyimage.com/250x325/000000/fff.png&text=Just+a+Test"
"loves" => 88
"downloads" => 280
"created_at" => "2018-01-01 13:26:47"
"updated_at" => "2018-01-02 10:10:32"
]
As you can see, the 'subjects' attribute is being stored as a string. I know there is attribute casting in 5.5 (I am running 5.5), but I am not too clear on how I would implement the example they have for Array & JSON Casting in my work above. https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting
Would anyone be willing to show me an example?
I'd rely on Attribute Casting for this, add a $casts property in your model and it will be done automatically.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Resource extends Model
{
use Searchable;
protected $primaryKey = 'objectID';
protected $casts = [
'subjects' => 'array',
];
public function toSearchableArray()
{
// Same function as you posted
}
}
You can also do it manually in your toSearchableArray method with $data['subjects'] = json_decode($this->subjects, true);
I answered with more details on this other posts: https://discourse.algolia.com/t/laravel-array-json-casting-to-algolia/4125/2

Laravel 4 Response

how to return response in laravel 4 like for this example ?
"key": {
"q1": "a3",
"q2": "a2",
"q3": "a1"
}
I do simple response
$key = KeyV2::all();
return Response::json(array(
'key' => $key
), 200);
result is
"key": {
"name": "q1",
"value": "a3"
}
but I need as I have described above.
I know that when I do ALL () it returns to me in this collection does not necessarily write toArray()
You can use lists() for that:
$key = KeyV2::lists('value', 'key');
return Response::json(array(
'key' => $key
));
(And 200 is unnecessary since it is the default value)

Deserialize multidimensional JSON API Response with JSMSerializerBundle

I work with Symfony2/JSMSerializerBundle.
Serializing flat json objects to PHP objects works great. But the API I use, gives a multidimensional Json response:
{
"Webmessage": {
"#version": "1.0",
"Header": {
"Country": "NL",
"Language": "NL"
},
"Content": {
"Filters": {
"Sizes": {
"Size": [
{
"#id": "241",
"#text": "3,5"
},
{
"#id": "55",
"#text": "36"
}
]
},
"Colours": {
"Colour": [
{
"#id": "159",
"#text": "wit"
},
{
"#id": "54",
"#text": "zwart"
}
]
}
}
}
}
}
As deserialized PHP I want something like this:
Array
(
[sizes] => Array
(
[0] => AppBundle\Entity\Filter Object
(
[id:AppBundle\Entity\Filter:private] => 1
[text:AppBundle\Entity\Filter:private] => Heren
)
[1] => AppBundle\Entity\Filter Object
(
[id:AppBundle\Entity\Filter:private] => 2
[text:AppBundle\Entity\Filter:private] => Dames
)
)
[colour] => Array
(
[0] => AppBundle\Entity\Filter Object
(
[id:AppBundle\Entity\Filter:private] =>56
[text:AppBundle\Entity\Filter:private] => Black
)
[1] => AppBundle\Entity\Filter Object
(
[id:AppBundle\Entity\Filter:private] => 212
[text:AppBundle\Entity\Filter:private] => Yellow
)
)
)
Who has tips how i can do this?
Thanks!
Maybe you can decode it first and then use the Normalizer to create the entities. Something like this:
$array= json_decode($json, true);
$valueToDenormalize = $array['value'];
$normalizer = new GetSetMethodNormalizer();
$entity = $normalizer->denormalize($valueToDenormalize, 'Your\Class');
Be aware, I have not tried this. I don't know if the normalizer will work this way, but I know it's used to normalize and denormalize between arrays and Symfony's entities.
For further investigation you could take a look at the Serializer docs:
http://symfony.com/doc/current/components/serializer.html
Or the Normalizer:
http://api.symfony.com/2.3/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.html
Here's something about json_encode:
http://php.net/manual/en/function.json-decode.php