Laravel Loop through nested array - json

{
"8": {
"id": "8",
"name": "Third Product",
"price": 3000,
"quantity": "1",
"attributes": {
"tax": 7.5,
"shop": "Edificeweb",
"image": "rp-4.jpg"
},
"conditions": []
},
"9": {
"id": "9",
"name": "The fourth",
"price": 200,
"quantity": "1",
"attributes": {
"tax": 7.5,
"shop": "Edificeweb",
"image": "product-2.jpg"
},
"conditions": []
}
}
I stored my cart as a json column in my order page... How do I check for authenticated user using whereJsonContains....
I tried
$Order=Order::whereJsonContains('cart->attributes->shop',Auth::user()->name)->get();
It returns empty array

If you're working with mysql you should try something like:
$Order = Order::whereJsonContains('cart->attributes', ['shop' => Auth::user()->name])->first();
With postgresql try with:
$Order = Order::whereJsonContains('cart->attributes', [['shop' => Auth::user()->name]])->first();
If it's case sensitivity you should try raw:
$Order = Order::whereJsonContains(DB::raw('lower("cart->attributes"::text)'),
[["shop" => strtolower(Auth::user()->name)]])->first();
I recommend that you save the objects without numbers as indicators, if you are saving it with numbers as indicators ("9", "8") you should try:
$Order = Order::whereJsonContains('cart->"$[*].attributes"', ['shop' => Auth::user()->name])->first();
btw, I would recommend that you use first instead of get but it would be better for you to try it and see what your convenience is ;)

Related

How to parameterize a part of string in a field of the response in karate

I am trying to print a response based on the particular parameters.
For that, I have the response from an API as below:
{
"ABC": {
"code": "ABC",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "0",
},
"priority": "1"
},
"DEF": {
"code": "DEF",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "1",
},
"priority": "1"
},
"GHI": {
"code": "GHI",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "2",
},
"priority": "1"
},
"JKL": {
"code": "JKL",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "0",
},
"priority": "1"
},
}
Here is the feature file that I am using to print that particular value:
Feature: Value extraction
Background:
* def all = [ABC,DEF,GHI,JKL]
Scenario: Extract response value
Given url
When method get
Then status 200
And def value = []
And eval for(var i=0;i<all.length;i++) {value.add(response['#(all[i])']["execution"]["status"]) }
And print value
I want to extract the value of all parameters whose status is "0".
print response["ABC"]["execution"]["status"]
The above line gives the result but I want to parameterise the ["ABC"] part
Any help on this? Is there any other way I can achieve this or am I doing something wrong to achieve this particular edge case?
I'm providing a sample below that answers multiple questions:
* def response =
"""
{
"ABC": {
"code": "ABC",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "0",
},
"priority": "1"
},
"DEF": {
"code": "DEF",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "1",
},
"priority": "1"
}
}
"""
# get all values in root json
* def items = $.*
* def code = 'ABC'
* def found = items.filter(x => x.code == code && x.execution.status == '0')
* assert found.length == 1
# the expression on the right below is pure JS
* match found[0] == response[code]
Note:
how to use json-path to simplify JSON, also refer: https://stackoverflow.com/a/68811696/143475
how to use the filter() API to "find" data using complex expressions, that can be parameterized, also see: https://github.com/karatelabs/karate#json-transforms
how to get the value of a key that can be dynamic and parameterized

Deep_search in big json object by method ruby

I have a problem with filtering JSON object in ruby!
1. My JSON object is a big array of two hashes.
2. That hashes includes another hashes that include another arrays and hashes (oh god! :c).
My goal is to output Big hash that contains concrete value!
Examples down below:
JSON file just like in
[#That's hash 0{
"id": 0,
"firstName": "",
"lastName": "",
"middleName": null,
"email": "",
"phones": [
null,
null
],
"groups": [{
"id": 0,
"name": ""
}],
"disabled": "",
"technologies": [{
"id": 0,
"name": "",
"children": [{
"id": 1,
"name": "",
"children": [{
"id": 2,
"name": "Farmer",
"children": []
}]
}]
}],
"fullName": ""
},
#That's hash1{
"id": 0,
"firstName": "",
"lastName": "",
"middleName": null,
"email": "",
"phones": [
null,
null
],
"groups": [{
"id": 0,
"name": ""
}],
"disabled": "",
"technologies": [{
"id": 0,
"name": "",
"children": [{
"id": 1,
"name": "",
"children": [{
"id": 2,
"name": "Not Farmer",
"children": []
}]
}]
}],
"fullName": ""
}
]
Pseudocode on ruby (what I want to):
file = File.read("example.json") #=> Reading JSON file
data_hash = JSON.parse(file, object_class: Hash) #=> Parsing JSON file
data = data_hash.filter #=> filter that hash if "technologies" is not empty!
data.get_hash_by_value(value) #=> For example i put "Not Farmer" in value, and that method must search in all data that (value) and output hash1 for me (because hash0 not include "Not Farmer")
That's big problem, i don't know what to do!!!
My thoughts is a recursive finding method..
I wrote my own functions. Maybe it can help someone.
def check_children(item)
return true if item["name"] == "Farmer"
item["children"].each do |child_item|
break if check_children(child_item)
end
return false
end
data_hash.each do |item|
next if item["technologies"].empty?
item["technologies"].each do |technologies_item|
next if technologies_item["children"].empty?
technologies_item["children"].each do |children_item|
data << item if check_children(children_item)
end
end
end

lodash sort an array of objects by a property which has an array of objects

I have a an object. I am able to sort the items by using lodash's _.orderBy().
However, in one of the scenario I have to sort by subject, which is an array of objects. Items inside the subject array are already sorted based on the name.
As subject is an array of the objects, I need to consider the first item for sorting.
[
{
"id": "1",
"name": "peter",
"subject": [
{
"id": "1",
"name": "maths"
},
{
"id": "2",
"name": "social"
}
]
},
{
"id": "2",
"name": "david",
"subject": [
{
"id": "2",
"name": "physics"
},
{
"id": "3",
"name": "science"
}
]
},
{
"id": "3",
"name": "Justin",
"subject": [
]
}
]
You can use _.get() to extract the name (or id) of the 1st item in subjects. If no item exists, _.get() will return undefined, which can be replaced with a default value. In this case, we don't want to use an empty string as a default value, since the order would change. Instead I'm checking if the value is a string, if it is I use lower case on it, if not I return it as is.
const arr = [{"id":"1","name":"peter","subject":[{"id":"1","name":"maths"},{"id":"2","name":"social"}]},{"id":"2","name":"david","subject":[{"id":"2","name":"physics"},{"id":"3","name":"science"}]},{"id":"3","name":"Justin","subject":[]}]
const result = _.orderBy(arr, o => {
const name = _.get(o, 'subject[0].name')
return _.isString(name) ? name.toLowerCase() : name
})
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Use _.sortBy with a comparison/sorting function argument. Your function itself can look into the receiving arguments subject key (I think its the subject you want to compare?)
Since you have the question also tagged with ES6 here is an JS only solution via Array.sort:
let arr = [ { "id": "1", "name": "peter", "subject": [ { "id": "1", "name": "maths" }, { "id": "2", "name": "social" } ] }, { "id": "2", "name": "david", "subject": [ { "id": "2", "name": "physics" }, { "id": "3", "name": "science" } ] }, { "id": "3", "name": "Justin", "subject": [] }, ]
const result = arr.sort((a,b) =>
a.subject.length && b.subject.length
? a.subject[0].name.localeCompare(b.subject[0].name)
: a.subject.length ? -1 : 1)
console.log(result)

How can I return an array of object based on matching ids?

I am trying to match the ids of two json files and return the matching objects. These are the 2 json files:
{
"een": {
"id": "100",
"title": "Entertainment and stuff"
},
"twee": {
"id": "107",
"title": "Sport for everyone"
},
"drie": {
"id": "108",
"title": "Eating is good"
}
}
This is the second one:
[
{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false
},
{
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false
}
]
As a result of the 2 matching idvalues I should get:
[
{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false,
"title": "Entertainment and stuff"
},
{
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false,
"title": "Sport for everyone"
}
]
I was wondering if there was a fancy way using lodash or something else and do this in a nice compact way?
One possible solution would be to use merge to merge two objects that have the id as the key. This can be done using keyBy on the array and also on the values of the first object. Intersection is used find ids that are in both arrays.
let list1 = {
"een": {
"id": "100",
"title": "Entertainment and stuff"
},
"twee": {
"id": "107",
"title": "Sport for everyone"
},
"drie": {
"id": "108",
"title": "Eating is good"
}
}
let list2 = [
{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false
},
{
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false
}
]
let o1 = _.keyBy(_.values(list1), 'id');
let o2 = _.keyBy(list2, 'id');
let matchingIds = _.intersection(_.keys(o1), _.keys(o2));
let result = _.chain(o1)
.pick(matchingIds)
.merge(_.pick(o2,matchingIds))
.values()
.value()
Building on #GruffBunny's answer, you want to take his result and filter out those ids that aren't found in o1 and o2.
let o1 = _.keyBy(_.values(list1), 'id'));
let o2 = _.keyBy(list2, 'id');
let idsToPull = _.difference( _.map(o1, 'id'), _.map(o2, 'id')) //["108"]
let merged = _.values(_.merge(o1, o2 ));
let result = _.filter(merged, function(obj){ return _.indexOf(idsToPull, obj.id) === -1 })

ActiveRecord get array inside array with three tables

I'm trying to output a json string with the ActiveRecord system in the Codeigniter framework.
The right syntax for my json string need to be:
{
"data": [
[
{
"name": "xxxx",
"city": "xxx",
"address": "xxx",
"image": "xxx",
"marketId": "1",
"products": [
"Id": "36",
"productId": "36",
"price": "120",
"discounts": "1",
"title": "xxx",
"category": "2",
"weight": "12.5",
"code": "EA123",
"isUnitized": "0",
"description": "xxxx",
"changed": "2014-04-08 15:09:16",
"units": "xxx"
]
}
]
]
Pay attention to the "products" array.
But the string that i'm getting from the code is not right, here is the wrong string:
{
"data": [
[
{
"name": "xxx",
"city": "xxx",
"address": "xx x",
"image": "xxx",
"marketId": "1",
"Id": "36",
"productId": "36",
"price": "120",
"discounts": "1",
"title": "xxx",
"category": "2",
"weight": "12.5",
"code": "EA123",
"isUnitized": "0",
"description": "xxx",
"changed": "2014-04-08 15:09:16",
"units": "xxx"
}
]
]
You can see that the product array is't showing like an array but as a regular string inside the main array.
Here is the code that have I built:
$this->db->select('*');
$this->db->from('markets');
$this->db->where("markets.marketId", $marketId);
$this->db->join('linkedPrices', 'linkedPrices.marketId = markets.marketId');
$this->db->join('products', 'products.Id = linkedPrices.productId');
$this->db->order_by("linkedPrices.price", "DESC");
$output[] = $this->db->get()->result();
So you can see here the join between the table. The goal is to show the products tables as individual array inside the markets array as you can see at the top example of the json string.
No not this way you gonna have array of products foreach your dataset it can be done by looping over your results and fetch the relevant product data
$result=new stdClass();
$this->db->select('*');
$this->db->from('markets');
$this->db->where("markets.marketId", $marketId);
$this->db->join('linkedPrices', 'linkedPrices.marketId = markets.marketId');
$this->db->order_by("linkedPrices.price", "DESC");
$result = $this->db->get()->result();
foreach($result as $r){
$result->products=$this->db->select('*')
->from('products')
->where('id',$r->productId)
->get()
->result();
}
$output[]=json_encode($result);