filter array elememts to add to listView - arrays

I am reading from my firebase database, which holds nested data in the following format which I want to add specific elements of to a listView;
group {
subgroup {
index[0]{
name: "Tom"
message: "hello"
}
index[1]{
name: "Dave"
message: "goodbye"
}
index[2]{
name: "Katie"
message: "morning"
}
}
}
What I want to do is add the name and message property to a listView in my app, an array is created when my app is launched with data from firebase, so I need to check for the name property and add to the list view when applicable.
I have used for loops and image visibility to display markers on a calendar, would a similar approach of looping through the array be the best option to create the list? I do need to create the list on specific dates on the calendar with 1 or more username entry in the same method.
By looping using the following code in my console shows what i want. yet i am struggling to translate into my list model, If i am just adding the name the below code works, but adding both to my list isn't working. My code is;
var nameArr = (JSON.stringify(value))
var parseData = JSON.parse(nameArr);
for(var index in parseData)
console.log("nameParse: ", parseData[index].name, ":", "detailsParse: ", parseData[index].message)
ListView {
id:eventListView
spacing: 4
clip: true
anchors.fill: parent
anchors.margins: 10
model: ListModel {id: model }
Component.onCompleted: {
model.clear();
var list = parseData;
for(var i in list)
model.append({"name": list[i].name, "details": list[i].message});
}
delegate: Label {
id: nameLabel
text: modelData.name
}
Label {
id: timeLabel
text: modelData.message
}
}

Javascript array could be used as a data source in this way:
ListView {
anchors.fill: parent
property var group: {
"subgroup": [
{
"name": "Tom",
"message": "hello"
},
{
"name": "Dave",
"message": "goodbye"
},
{
"name": "Katie",
"message": "morning"
}
]
}
model: group.subgroup
delegate: Text { text: modelData.name }
}

Related

Swiftui User Multiple Selection To Array of Object

I have the following response from API
"features": [
{
"name": "Safety",
"_id": "636a638959d10a2603b8d645",
"values": [
Array of String
]
},
{
"name": "Entertainment",
"_id": "636a64312bbe0cd292a1ffc6",
"values": [
Array of String
]
Which I decode it with :
struct Feature : Codable , Hashable{
var name : String = ""
var values : [Value] = []
}
struct Value : Codable, Hashable{
var value : String = ""
var unit : String = ""
}
And in the view is render it like :
var body: some View {
VStack{
HStack{
Text("Choose Your Features").font(Font.body.bold())
Spacer()
}.padding(.leading, 15)
ScrollView(.vertical, showsIndicators: false){
VStack{
ForEach(Array(features.enumerated()), id: \.offset) { featureIndex, feature in
HStack{
Text(feature.name).font(Font.body.bold())
Spacer()
}.padding(.bottom , 10)
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing : 10){
ForEach(Array(feature.values.enumerated()), id: \.offset) { valueIndex, value in
FeatureCell(isSelected: $isSelected, value: value).onTapGesture{
// here
}
}
}
Divider().padding(10)
}
}.padding(15)
}
}
}
}
The user may select multiple item from each feature values list, Now Im really confused about how to store these selections in an array of features object again, I tried almost every thing like Array, Set and Dictionaries but could not reach any solution.
Update : This is the json object I should send back
{
"features": [
{
"Safety": [
"value1",
"value9",
"value3"
]
},
{
"Entertainment": [
"value7",
"value2",
"value8"
]
}
]
}
Any help or ideas will be much appreciated
You usually want to use a Set to store which items are selected. This set should be a State variable instantiated in the parent view. The onTapGesture closure will add or remove the value to the set. If the FeatureCell needs to know whether the value is selected, simply use the .contains method.
struct FeatureValueSelectionView: View {
// The feature whose values we are displaying
let feature: Feature
// Note: You may have to manually conform Value to the Hashable protocol
#State private var selectedValues = Set<Value>()
var body: some View {
ForEach(feature.values) { value in
FeatureCell(selected: selectedValues.contains(value), value: value)
.onTapGesture { selectedValues.toggle(value) }
}
}
}
For toggling a value in a set, I like to use this simple extension:
extension Set {
public mutating func toggle(_ element: Element) {
if self.contains(element) {
self.subtract([element])
} else {
self.insert(element)
}
}
}

How to generate an array of objects in Alpine.data with Livewire Eloquent collection and Adding properties in those js objects

and thanks for your attention and help,
I have a Collection in my livewire controller. This collection contains a list of players, with some properties : here we will just focus on id and name.
So we can imagine that we have 3 players in the collection :
Players[0] : 'id'=>1, 'name'=>'Yann';
Players[1] : 'id'=>2, 'name'=>'Robert';
Players[2] : 'id'=>3, 'name'=>'Jessica';
I need to get these players in my alpine data.
I can easily get these players in Alpine with the #js method :
window.addEventListener('alpine:init', () => {
Alpine.data('data', () => ({
players: #js($players),
}))
})
So, now I have in my alpine.data :
players: [
{ id: 1, name: 'Yann' },
{ id: 2, name: 'Robert' },
{ id: 3, name: 'Jessica' },
]
Now I can easily display the players in my html with a template x-for :
<template x-for="player in players">
<p x-text="player.name"></p>
</template>
But I want to add some additionnal properties in each player object. Those properties will be updated in front depending user's actions.
I would like to get something like this :
players: [
{ id: 1, name: 'Yann', touched20: 0, touched15: 0 },
{ id: 2, name: 'Robert', touched20: 0, touched15: 0 },
{ id: 3, name: 'Jessica', touched20: 0, touched15: 0 },
]
All additionnal properties are the same for each object in the array, so I imagine i could use a foreach loop to put them in the objects.
But I can't see and don't understand how i can include a loop in my alpine.data script to do this.
Anyone could help me ?
I edit my question because I found a solution :
I just make a loopPlayers function outside of my alpine data and call this function in the alpine data :
function loopPlayers() {
let players = [];
const livewirePlayers = #js($players);
livewirePlayers.forEach(element => {
players.push(element);
});
players.forEach(function(element) {
element.touched15 = 0;
})
return players;
}
And in alpine.data :
players: loopPlayers(),
Now I have my collection of players from my livewire controller & I have new properties for each element of the collection in the js data
That was easy, as usual I guess :)

Add subelement to JSON array

I have the following code where I design the format of a JSON-array dynamically from variables ==>
var Title = '"text_title"'
var Topic2 = '"text_topic2"'
var jsonData = [ ];
createWantedJSON("title", data[i].topic, jsonData)
function createWantedJSON(title, Topic2, arr) {
arr.push({
"Topic": title,
[Topic2] : {
"Topic3": [{
"Subitem1": "Text1",
"Subitem2": "Text2",
"Subitem3": "Text3"
}]
}
}
This goes fine for the key and value which are not nested. But I don't know how to make it dynamic for the content of Topic3. I tried making a variable with the following content =>
'"Subitem1": "Text1", "Subitem2": "Text2", "Subitem3": "Text3"' but then of course it sees the content as one string and not as elements of the nested Topic3 array. I guess this isn't that hard but I can't seem to fix it.

update single item within array where multiple conditions apply to any array item

I have a basic mongoose model with an attribute instruments which represents an array. Therefore it consists multiple items, which each have the following attributes: name, counter. The document itself has an autogenerated _id of type ObjectID.
Model
var ParticipationSchema = new Schema({
instruments: [{
name: String,
counter: Number
}],
// etc.
},
{
timestamps: true
});
I'd like now to change exactly 1 item within the instruments array, only if it matches the following requirements:
The document id has to equal 58f3c77d789330486ccadf40
The instruments-item's name which should be changed has to equal 'instrument-1'
The instrument-item's counter has to be lower than 3
Query
let someId = '58f3c77d789330486ccadf40';
let instrumentName = 'instrument-1'
let counter = 3;
Participation.update(
{
$and: [
{ _id: mongoose.Types.ObjectId(someId) },
{ 'instruments.name': instrumentName },
{ 'instruments.counter': { $lt: counter } }
]},
{
$set: {
'instruments.$.currentcounter' : counter
}
},
(err, raw) => {
// ERROR HANDLING
}
});
Let's assume I have 3 entries within the instruments-attribute:
"instruments": [
{
"name": "instrument-1",
"counter": 2
},
{
"name": "instrument-1",
"counter": 2
},
{
"name": "instrument-1",
"counter": 2
}
]
Desired behaviour: change the first element's counter attribute to 3, no matter, when running the update code 1 time, do no action when running it more times.
Actual behaviour:
it changes the 1st element's counter attribute to 3 when running it the 1st time
it changes the 2nds element's counter attribute to 3 when running it the 2nd time
it changes the 3rds element's counter attribute to 3 when running it the 3rd time
Although the queries are anded, they don't seem to run element-wise. To resolve the issue, $elemMatch can be used:
Participation.update({
_id: mongoose.Types.ObjectId(someId),
'instruments': {
$elemMatch: {
'name': instrumentName,
'counter': { $lt: counter } }}
},
// etc.
more info:
API reference on $elemMatch
Thanks to #VEERAM's for pointing out that this kind of behaviour is also documented the mongodb homepage.

How to search array of object in backbone js

how to search array of object in backbone js.The collection contain persons model.
[{
name: "John",
age: "18",
likes: {
food: "pizza",
drinks: "something",
}
},
......
]
how can i get persons who likes something.
i did try collection.where({likes :{food : "pizza"}});
Since your food property is in an object on the Person's attributes, using where (which by default just looks at the flat attributes) isn't going to work. You can use the filter method to apply a truth test to all of the items in your collection and just get the ones that pass.
In the code you posted, it doesn't look like you have a Backbone Collection proper, just a regular array of objects.
Since Underscore is on the page, you can use it to help filter through your list.
var people = [
{
name: "John",
age: "18",
likes: {
food: "pizza",
drinks: "something",
}
},
......
];
var likesPizza = _.filter(people, function(person) {
return person.likes.food === "pizza";
});
If it is in fact a Backbone Collection, you can use
this.collection.filter(people, function(person) {
return person.get('likes').food === "pizza";
});

Resources