Finding image uri in a nested array - arrays

I am trying to get the image uri from this payload. I can get to the image array with this but no further.
bikesArray.map(bikes => bikes.customerBikeImage.assets)
The entire payload is like this.
{
"customerBikeComponents": "SRAM",
"customerBikeCondition": "Used",
"customerBikeImage": {
"assets": [
Array
]
},
"customerBikeMake": "Planet C",
"customerBikePrice": "1500",
"customerBikeRegister": "Yes",
"customerBikeSize": "80"
},
Then the array within the payload is:
[
{
"fileName": "BA459947-3C2A-49CE-8E44-D74B92D5EA49.jpg",
"fileSize": 3583973,
"height": 3088,
"type": "image/jpg",
"uri": "file:///var/mobile/Containers/Data/Application/DF4C4FB4-191F-4101-9A11-4FD728B3CE4B/tmp/BA459947-3C2A-49CE-8E44-D74B92D5EA49.jpg",
"width": 2316
}
],
I am trying to get to the uri and assign that to a state.
i have tried several different ways to no avail and thought I would get some help.

hope this will help,
if you have mutiple imageUri
and you want your end result looking like that:
[
[www.sampleImage1.jpg,www.sampleImage2.jpg],
[www.sample2Image1.jpg,www.sample2Image2.jpg]
]
you need to map on the nested array as well.
bikesArray.map(
bike =>{
let imageUri;
/** if there are multiple uri */
imageUri= bike.customerBikeImage.assets.map(fileData=>fileData.uri)
return imageUri
}
)
if you have only one imageUri in the array
and you want your end result looking like that:
[
www.sampleImage1,
www.sample2Image1
]
just take the first element.
bikesArray.map(
bike =>{
let imageUri;
/*if there is only one uri */
imageUri= bike.customerBikeImage.assets[0].uri
return imageUri
}
)

You are trying to access Array when your data is Object.
const dataDB = {
customerBikeComponents: "SRAM",
customerBikeCondition: "Used",
customerBikeImage: {
assets: [
[
{
fileName: "BA459947-3C2A-49CE-8E44-D74B92D5EA49.jpg",
fileSize: 3583973,
height: 3088,
type: "image/jpg",
uri:
"file:///var/mobile/Containers/Data/Application/DF4C4FB4-191F-4101-9A11-4FD728B3CE4B/tmp/BA459947-3C2A-49CE-8E44-D74B92D5EA49.jpg",
width: 2316
}
]
]
},
customerBikeMake: "Planet C",
customerBikePrice: "1500",
customerBikeRegister: "Yes",
customerBikeSize: "80"
};
Try to use property accessors and pick first item of assets Array using [0] The full route:
data.customerBikeImage.assets[0][0].uri
Also check this codesandbox react example where assets array has object child.

Related

Mongoose find all documents that have a string in an array

I've a question:
How i can find all documents that have a string in an array using mongoose?
For example, my document:
<Model>.findMany(/* code that i need */).exec() // return all documents that have an array called "tags" that includes tag "test"
{
"_id": {
"$oid": "61b129b7dd0906ad4a2efb74"
},
"id": "843104500713127946",
"description": "Server di prova",
"tags": [
"developers",
"programming",
"chatting",
"ita"
],
"shortDescription": "Siamo un server nato per chattare e aiutare programmatori su Discord!",
"invite": "https://discord.gg/NdqUqHBxz9",
"__v": 0
}
For example, if I need to get all documents with ita tag, I need to get this document.
If the document doesn't have ita tag in array tag, I don't need it and the code will not return it.
Thanks in advance and sorry for bad english.
Actually you can just request tags to be test since mongoose looks for every tags entry
so this:
await Test.insertMany([{ tags: ["test"] }, { tags: ["Notest"] }])
let res = await Test.find({ "tags": "test" })
console.log(res)
}
returns that:
[
{
_id: new ObjectId("61b8af02c3effad21a5d7187"),
tags: [ 'test' ],
__v: 0
}
]
2 more neat things to know:
This works no matter how many entries tags has, as long test is one of ethem
This also enables you to change the entrie containing the "test" by using positional $ operator, so something like {$set: "tags.$": "smthNew"} will change all the test entries
Example for 2nd:
let res = await Test.updateMany({ "tags": "test" }, { $set: { "tags.$": "new" } }, { new: true })

How can i make two objects out of one object, dividing them by a value in the object with lodash

Consider this object, with two channels with NL language and one with EN language:
[
{
"name": "De Redactie",
"channels": [
{
"name": "headlines",
"pubDate": "2017-05-15 09:15:00",
"language": "nl",
"items": [
]
},
{
"name": "headlines English",
"pubDate": "2017-05-14 18:05:00",
"language": "en",
"items": [
]
},
{
"name": "politiek",
"pubDate": "2017-05-14 20:11:00",
"language": "nl",
"items": [
]
}
]
}
]
How can i divide them so that i can get this result:
[
{
"name": "De Redactie",
"channels": [
{
"name": "headlines",
"pubDate": "2017-05-15 09:15:00",
"language": "nl",
"items": [
]
},
{
"name": "politiek",
"pubDate": "2017-05-14 20:11:00",
"language": "nl",
"items": [
]
}
]
}
{
"name": "De Redactie",
"channels": [
{
"name": "headlines English",
"pubDate": "2017-05-14 18:05:00",
"language": "en",
"items": [
]
}
]
}
]
Mind you that this is dummyData. The actual data can contain x amount of one language and y amount of the second or third or fourth ...
I have tried looking in the lodash documentation for the correct combination of functions. Also tried various complex forEach structures, but could not wrap my head around it.
Preferably a solution with lodash or typescript, as i'm working in Angular 4.
Iterate the array with Array#map. For each object, extract the array of channels using destructuring with object rest. Iterate the channels using Array#reduce and group channels with the same language to a Map. Convert back to an array by spreading the Map's values iterator.
Create an array of objects, by mapping them and assigning the group as the channels prop of the object. Flatten the array by spreading into Array#concat:
const data = [{"name":"De Redactie","channels":[{"name":"headlines","pubDate":"2017-05-15 09:15:00","language":"nl","items":[]},{"name":"headlines English","pubDate":"2017-05-14 18:05:00","language":"en","items":[]},{"name":"politiek","pubDate":"2017-05-14 20:11:00","language":"nl","items":[]}]}];
const result = [].concat(...data.map(({ channels, ...rest }) => {
const channelGroups = [...channels.reduce((m, channel) => {
m.has(channel.language) || m.set(channel.language, []);
m.get(channel.language).push(channel);
return m;
}, new Map()).values()];
return channelGroups.map((channels) => ({
...rest,
channels
}));
}));
console.log(result);
way with lodash:
const res = _.chain(arr)
.flatMap(item => _.map( // get array of channels with parent name
item.channels,
channel => _.assign({}, channel, { parentName: item.name })
))
.groupBy('language') // group channels by language
.values() // get channel arrays for each lang
.map(langArrs => ({ // set finished structure
name: _.first(langArrs).parentName, // get name for lang channels
channels: _.omit(langArrs, ['parentName']) // set channels without parent name
}))
.value();

Updating Nested Array Mongoose

I am working on an express js application where I need to update a nested array.
1) Schema :
//Creating a mongoose schema
var userSchema = mongoose.Schema({
_id: {type: String, required:true},
name: String,
sensors: [{
sensor_name: {type: String, required:true},
measurements: [{time: String}]
}] });
2)
Here is the code snippet and explanation is below:
router.route('/sensors_update/:_id/:sensor_name/')
.post(function (req, res) {
User.findOneAndUpdate({_id:req.body._id}, {$push: {"sensors" :
{"sensor_name" : req.body.sensor_name , "measurements.0.time": req.body.time } } },
{new:true},function(err, newSensor) {
if (err)
res.send(err);
res.send(newSensor)
}); });
I am able to successfully update a value to the measurements array using the findOneAndUpdate with push technique but I'm failing when I try to add multiple measurements to the sensors array.
Here is current json I get if I get when I post a second measurement to the sensors array :
{
"_id": "Manasa",
"name": "Manasa Sub",
"__v": 0,
"sensors": [
{
"sensor_name": "ras",
"_id": "57da0a4bf3884d1fb2234c74",
"measurements": [
{
"time": "8:00"
}
]
},
{
"sensor_name": "ras",
"_id": "57da0a68f3884d1fb2234c75",
"measurements": [
{
"time": "9:00"
}
]
}]}
But the right format I want is posting multiple measurements with the sensors array like this :
Right JSON format would be :
{
"_id" : "Manasa",
"name" : "Manasa Sub",
"sensors" : [
{
"sensor_name" : "ras",
"_id" : ObjectId("57da0a4bf3884d1fb2234c74"),
"measurements" : [
{
"time" : "8:00"
}
],
"measurements" : [
{
"time" : "9:00"
}
]
}],
"__v" : 0 }
Please suggest some ideas regarding this. Thanks in advance.
You might want to rethink your data model. As it is currently, you cannot accomplish what you want. The sensors field refers to an array. In the ideal document format that you have provided, you have a single object inside that array. Then inside that object, you have two fields with the exact same key. In a JSON object, or mongo document in this context, you can't have duplicate keys within the same object.
It's not clear exactly what you're looking for here, but perhaps it would be best to go for something like this:
{
"_id" : "Manasa",
"name" : "Manasa Sub",
"sensors" : [
{
"sensor_name" : "ras",
"_id" : ObjectId("57da0a4bf3884d1fb2234c74"),
"measurements" : [
{
"time" : "8:00"
},
{
"time" : "9:00"
}
]
},
{
// next sensor in the sensors array with similar format
"_id": "",
"name": "",
"measurements": []
}],
}
If this is what you want, then you can try this:
User.findOneAndUpdate(
{ _id:req.body._id "sensors.sensor_name": req.body.sensor_name },
{ $push: { "sensors.0.measurements": { "time": req.body.time } } }
);
And as a side note, if you're only ever going to store a single string in each object in the measurements array, you might want to just store the actual values instead of the whole object { time: "value" }. You might find the data easier to handle this way.
Instead of hardcoding the index of the array it is possible to use identifier and positional operator $.
Example:
User.findOneAndUpdate(
{ _id: "Manasa" },
{ $push: { "sensors.$[outer].measurements": { "time": req.body.time } } }
{ "arrayFilters:" [{"outer._id": ObjectId("57da0a4bf3884d1fb2234c74")}]
);
You may notice than instead of getting a first element of the array I specified which element of the sensors array I would like to update by providing its ObjectId.
Note that arrayFilters are passed as the third argument to the update query as an option.
You could now make "outer._id" dynamic by passing the ObjectId of the sensor like so: {"outer._id": req.body.sensorId}
In general, with the use of identifier, you can get to even deeper nested array elements by following the same procedure and adding more filters.
If there was a third level nesting you could then do something like:
User.findOneAndUpdate(
{ _id: "Manasa" },
{ $push: { "sensors.$[outer].measurements.$[inner].example": { "time": req.body.time } } }
{ "arrayFilters:" [{"outer._id": ObjectId("57da0a4bf3884d1fb2234c74"), {"inner._id": ObjectId("57da0a4bf3884d1fb2234c74"}}]
);
You can find more details here in the answer written by Neil Lunn.
refer ::: positional-all
--- conditions :: { other_conditions, 'array1.array2.field_to_be_checked': 'value' }
--- updateData ::: { $push : { 'array1.$[].array2.$[].array3' : 'value_to_be_pushed' } }

ForEach Loop JSON AngularJS Object in Object

I am very new to AngularJS and I am trying to learn how to get deeper into a JSON object that has objects inside of objects and sometimes even arrays. This is a "simplified" version I am working with and I hope it will help me get a basic understanding so I can do the rest on my own.
json
values = {
"profile": {
"fields": {
"number-of-fields": "700",
"inside": [
"test1",
"test2"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
}
code
angular.forEach(values, function(value, key) {
console.log(key + ': ' + value);
// I know I need to loop inside of each object I beleieve
});
http://jsfiddle.net/ygahqdge/184/
The basics
Traverse object properties with a dot ., traverse array indexes with an index reference, [0|1|2|etc.].
What about your object?
var yoObject = {
"profile": {
"fields": {
"number-of-fields": "700",
"inside": [
"test1",
"test2"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
}
Get the inside values:
// object object object array
yoObject.profile.fields.inside.map(console.log, console) // ["test1", "test2"]
Get the id:
// object property
yoObject.id // "12312312333645"
Get all properties of the fields object:
Object.keys(yoObject.profile.fields) // ['number-of-fields', 'inside', 'type', 'values']
Get all values of the properies from above:
fields = yoObject.profile.fields
Object.keys(fields).map(key => console.log(fields[key])) // ["700", ["test1", "test2"], "test", "450"] // Note: Order isn't guaranteed
Just play about with things. Throw the object in the console and start to manually traverse it. Then try to loop over things.
Have fun!
Note: I tested none of that! :P
this is a question in regards on the right way to loop deep in JSON
objects – #user2402107
There's no right way. Sometimes you'll need to be fully dynamic, other times you can hardcode paths into nested properties and values.
Fiddle-Diddle
Nest as many times as you need:
angular.forEach(values, (value, key) => {
console.log("Value for", key, ":", value);
angular.forEach(value, (value, key) => {
console.log("Value for", key, ":", value);
angular.forEach(value, (value, key) => {
console.log("Value for", key, ":", value);
})
})
});
You can log the whole object to console. By using F12 tool, you can browse the object in the browser.
console.log(objectName);
angular.forEach works on arrays. lets suppose you have an array of objects as this
var values = [{
"profile": {
"fields": {
"number-of-fields": "700",
"interpertation": [
"whenever this is ready"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
},
{
"profile": {
"fields": {
"number-of-fields": "700",
"interpertation": [
"whenever this is ready"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
}]
you can explore each object and its properties like this
angular.forEach(values, function(value, key) {
console.log(value.profile.fields.values);
});
you can use . notation to access propertes

When do the Facebook graph api endpoints return an array wrapped in a { data: ... } object?

Some Facebook graph api endpoints return arrays like this:
"likes": {
"data": [
{
"id": "000000",
"name": "Somebody"
}
],
"paging": {
"cursors": {
"after": ".....",
"before": "....."
}
}
}
While others return arrays like this:
"actions": [
{
"name": "Comment",
"link": "https://www.facebook.com/000000/posts/00000"
},
{
"name": "Like",
"link": "https://www.facebook.com/00000/posts/00000"
}
]
Does anyone know of where in the documentation Facebook explains when an array is going to be returned wrapped in a { data: [...] } object? As far as I know, facebook just lists everything that is an array as array and doesn't explain when a data object will be returned.
I guess I can assume that if something can be "paged" that it will be in a data structure...
Am I missing some documentation about Facebook data types somewhere?
You are right, they seem to list everything that is an array as array.
For instance, in the documentation for the Post Endpoint, the return type for both "likes" and "actions" is listed as an array.
Likes
...
Array of objects containing the id and name fields.
Requesting with summary=1 will also return a summary object
containing the total_count of likes.
Actions
...
Array of objects containing the name and link
I think that's why you have to query the actual end point, and inspect the JSON (like you are doing) and figure out what is actually coming back.
No wonder the Facebook API is the proud winner of the "Worst API" Award!
Any feed(feeds/posts)(that is every array) you retrieve will be retured in data object, inside this data object the array will be there.Also the friend list is embedded in data object,which will have array of objects. Something like this:
{"data": [
{
"id": "..",
"name": ".."
}
],
"paging": {
"cursors": {
"after": ".....",
"before": "....."
}
}
}
While in all other api requests , which do not return an array, have structure like this:
{
"id": "..",
"name": ".."
}

Resources