I have a column in my db for saving a users' settings. This is what the data structure looks like:
{"email":{"subscriptions":"{\"Foo\":true,\"Bar\":false}"}}
I am using a vue toggle to change the status of each property (true/false). Everything seems to be working, however when I save, I am wiping out the structure and saving the updated values like this:
{\"Foo\":true,\"Bar\":false}"}
php
$user = auth()->user();
$array = json_decode($user->preferences['email']['subscriptions'], true);
dd($array);
The above gets me:
array:2 [
"Foo" => true
"Bar" => false
]
So far so good...
$preferences = array_merge($array, $request->all());
dd($preferences);
Gets me:
array:2 [
"Foo" => true
"Bar" => true
]
Great - the values are now picking up the values passed in from the axios request. Next up; update the user's data:
$user->update(compact('preferences'));
Now my data looks like this:
{"Foo":true,"Bar":true}
The values are no-longer nested; I've wiped out email and subscriptions.
I've tried this:
$user->update([$user->preferences['email']['subscriptions'] => json_encode($preferences)]);
But it doesn't seem to save the data. How can I use the $preferences variable to update the data - and keep the data nested correctly?
You can create an array with the structure you want the resulting json to have. So, for this json:
{
"email":{
"subscriptions":{
"Foo":true,
"Bar":false
}
}
}
you can create an array like this:
[
'email' => [
'subscriptions' => [
'Foo' => true,
'Bar' => false
]
]
]
an then, encode the entire structure:
json_encode([
'email' => [
'subscriptions' => [
'Foo' => true,
'Bar' => false
]
]
]);
So, in your code, as you already have the nested array in the $preferences variable, I think this should work:
$json_preferences = json_encode([
'email' => [
'subscriptions' => $preferences
]
]);
Then you can update the user 'preferences' attribute (just for example):
User::where('id', auth()->user()->id)->update(['preferences' => $json_preferences]);
or
$user = auth()->user();
$user->preferences = $json_preferences;
$user->save();
Related
I have the following perl code in where I have a perl structure as follows:
`
use Data::Dumper;
my %data = (
'status' => 200,
'message' => '',
'response' => {
'name' => 'John Smith',
'id' => '1abc579',
'ibge' => '3304557',
'uf' => 'XY',
'status' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' )
}
);
my $resp = $data{'status'};
print "Response is $resp \n";
print Dumper(%data->{'response'});
Getting the status field works, however If I try something like this:
my $resp = $data{'response'}
I get Response is HASH(0x8b6640)
So I'm wondering if there's a way I can extract all the data of the 'response' field on the same way I can do it for 'status' without getting that HASH...
I've tried all sort of combinations when accessing the data, however I'm still getting the HASH back when I try to get the content of 'response'
$data{'response'} is the correct way to access that field on a hash called %data. It's returning a hash reference, which prints out by default in the (relatively unhelpful) HASH(0x8b6640) syntax you've seen. But if you pass that reference to Dumper, it'll show you everything.
print Dumper($data{'response'});
to actually access those subfields, you need to dereference, which is done with an indirection -> operation.
print $data{'response'}->{'name'}
The first access doesn't need the -> because you're accessing a field on a hash variable (i.e. a variable with the % sigil). The second one does because you're dereferencing a reference, which, at least in spirit, has the $ sigil like other scalars.
Thanks for your posts. I fixed the code as follows:
use Data::Dumper;
my %data = (
'status' => 200,
'message' => '',
'response' => {
'name' => 'John Smith',
'id' => '1abc579',
'ibge' => '3304557',
'uf' => 'XY',
'status' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' )
}
);
my $resp = $data{'response'};
print Dumper($resp);
Now it works like a charm, and I'm able to get the data I want.
I have in my database values with this form :
["email1#gmail.com","email2#gmail.com"]
I'm using laravel and I want to loop on this variable to get each element for example get the element : email1#gmail.com.
I tried the following code :
I have the following array :
$emails :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["email3#gmail.com","email4#gmail.com"]"
]
So I'm using the following code to get each element :
$var = array();
foreach ($emails as $key => $value) {
$var[] = $value;
}
I get the following result :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["email3#gmail.com","email4#gmail.com"]"
]
If you have any idea , please help
UPDATE
I have the following array :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["hajar.boualamia33#gmail.com","guernine.khadija#gmail.com"]"
]
And I did the following method :
$emailss = collect($emails)->flatten()->all();
dd($emailss);
I get the following result :
array:2 [▼
0 => "["email1#gmail.com","email2#gmail.com"]"
1 => "["hajar.boualamia33#gmail.com","guernine.khadija#gmail.com"]"
]
Update
Ha, tricky one. It seems that you have a PHP expression (an array) stored. So in order to extract the arrays, we need to evaluate them first.
Try this instead:
$elements = [
"['email1#gmail.com','email2#gmail.com']",
"['email3#gmail.com','email4#gmail.com']",
];
$emails = collect($elements)
->map(function ($element) {
return (eval("return \$element = " . $element . ';'));
})
->flatten()
->all();
Try this:
$elements = [
['email1#gmail.com','email2#gmail.com'],
['email3#gmail.com','email4#gmail.com'],
];
$emails = collect($elements)->flatten()->all();
This will get you:
=> [
"email1#gmail.com",
"email2#gmail.com",
"email3#gmail.com",
"email4#gmail.com",
]
Check this method on the docs.
$data = User::find()
->select('id, name')
->where(['status' => 'active'])
->orderBy('id DESC')
->asArray()
->all();
[
[0]=>[
id=>1
name="test"
]
[1]=>[
id=>2
name="test1"
]
]
What I want is array which looks similar to this. Mapping the id with name so it can be accessed and checked.
[
[1]=>'test'
[2]=>'test1'
]
Instead of using the ArrayHelper you can directly achieve the desired output by using indexBy() and column() within your query:
$data = User::find()
->select(['name', 'id'])
->where(['status' => 'active'])
->orderBy(['id' => SORT_DESC])
->indexBy('id')
->column();
indexBy() defines the array key, while column() will take the first column in the select condition as value.
Try this
Add the below namespace and use the arrayhelper of Yii2 to map
use yii\helpers\ArrayHelper
$userdata = ArrayHelper::map($data, 'id', 'name');
I want to encode the result of a MySQL query into a JSON string using JSON::XS. The JSON string needs to look like this
{
"database" : "dbname"
"retentionPolicy" : "mytest",
"tags" : {
"type" : "generate",
"location" : "total",
"source" : "ehz"
},
"points" : [{
"precision" : "ms",
"timestamp" : "ts1",
"name" : "power",
"values" : {
"value" : "val1"
}
}, {
"precision" : "ms",
"timestamp" : "ts2",
"name" : "power",
"values" : {
"value" : "val2"
}
}, {
"precision" : "ms",
"timestamp" : "ts3",
"name" : "power",
"values" : {
"value" : "val3"
}
}
]
}
The points array with each point's values element is giving me immense headaches.
Here is the code block that generates the JSON
my %json_body = (
'database' => $db_name,
'retentionPolicy' => $retention,
'tags' => {
'source' => $metric_source,
'type' => $metric_type,
'location' => $metric_location
}
);
# loop through mysql result
while ( ($timestamp, $value) = $query->fetchrow_array() ) {
my %json_point1 = (
'name' => $series_name,
'timestamp' => ($timestamp * 1),
'precision' => "ms"
);
%json_point2 = ('value' => $value);
%json_values = (%json_point1, 'values' => \%json_point2);
push(#all_values, \%json_values);
}
$query->finish();
# Encode json
my %json_data = (%json_body, "points" => \#all_values);
$influx_json = encode_json(\%json_data);
I think the line push(#all_values, \%json_values) is my problem. If I pass %json_data as a hash reference, only the last value from the while loop is retained. If I use %json_values directly, the encoded JSON is messed up because it loses the structure.
Any hint would be appreciated. And please bear with me: this array and hash references are already making my head explode.
I'm pretty sure you problem will be because you're using a globally scoped hash for %json_point and %json_point2.
You see, the root of this is - you simply don't get a list of hashes. You get a list of hash references.
So the problem here is - when you push a reference to your hash into #all_values - you're pushing the same reference each time. But then you're overwriting the contents of the hash that you're referencing.
Try this:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_thing;
my #all_values;
for ( 1..3 ) {
%hash_thing = ( "test" => $_ );
push ( #all_values, \%hash_thing ) ;
}
print join ( "\n", #all_values );
print Dumper \#all_values;
And you'll see you have the same 'value' 3 times:
HASH(0x74478c)
HASH(0x74478c)
HASH(0x74478c)
And so if you dump it, then of course - you don't get the right array - and so your encoded JSON doesn't work either.
$VAR1 = [
{
'test' => 3
},
$VAR1->[0],
$VAR1->[0]
];
The simplest fix is to use my to scope the hashes to the loop. (And turn on use strict; and use warnings if you haven't.)
Alternatively, you can use a hash reference like this:
my #all_values;
my $hash_ref;
for ( 1..3 ) {
$hash_ref = { "test" => $_ };
push ( #all_values, $hash_ref ) ;
}
print #all_values;
print Dumper \#all_values;
Because $hash_ref is a scalar, and it's a reference to an anonymous hash, it can be inserted into the array by value, rather than by reference.
I have Dumper outputting data correctly:
'Apps' => [
\{
'name' => '1'
},
\{
'name' => '2'
},
\{
'name' => '3'
},
\{
'name' => '4'
},
\{
'name' => '5'
},
\{
'name' => '6'
},
\{
'name' => '7'
}
],
'code' => 'SUCCESS'
};
But when I convert it to JSON I have a lot of problems:
my #jsonapps;
my #apps = map { $_ } keys %glob;
my %hash;
$hash{'code'} = 'SUCCESS';
for (#apps) {
my $app = { 'name' => $_ };
push (#jsonapps, \$app);
}
# $hash{'Apps'} = \#jsonapps;
my $jsonfinal = encode_json \%hash;
print $jsonfinal;
It definitely has to do when with I try to add an array of hashes in:
$hash{'Apps'} = \#jsonapps;
But I'm having a problem doing that since all the hashes have the same key "name". I need my output to look like:
{"code":"SUCCESS","Apps":[{"name":"1"},{"name":"2"},{"name":"3"},{"name":"4"},{"name":"5"},{"name":"6"},{"name":"7"}]}
Thanks, I appreciate the help - I've scoured everywhere to figure out how to do this, and I'm just banging my head against the wall now. Thanks!
Notice the extra \ in your dump output.
'Apps' => [
\{
'name' => '1'
},
This is because it they are references to hash references. The problem code is here:
for (#apps) {
my $app = { 'name' => $_ };
push (#jsonapps, \$app);
}
$app is already a hashref since you use braces and assign it to a scalar. But adding the \ in front when you push it to #jsonapps means you are pushing the reference to the hashref. You don't need to make it a reference because it is already a reference. You just need to omit the \.
for (#apps) {
my $app = { 'name' => $_ };
push (#jsonapps, $app);
}