I have what is essentially a questionnaire in the form of a SQL model.
User answers the questions, creates the item. With the item loaded, how can I loop through the values? I'm new to JS and GAM, but I've tried the below and can only seem to get the name of the fields, not its value.
function generateScore(){
ds = app.datasources.Checklist.item;
for (var x in ds){
if (ds.x === 'Safe'){
console.log("Passed");
} else {
console.log("Failed");
}
}
}
Output will be 'Fail' as 'ds.x' is only returning the name of the field and not its value.
It's probably really simple, but can somebody guide me in the right direction?
Thanks
Short answer: In your function change ds.x to ds[x]:
function generateScore(){
ds = app.datasources.Checklist.item;
for (var x in ds){
if (ds[x] === 'Safe'){
console.log("Passed");
} else {
console.log("Failed");
}
}
}
TL;DR
There are Other ways of looping through the values of an object.
Let's assume the following object:
const obj = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
};
You can use the Object.keys syntax.
JS ES6 answer:
Object.keys(obj).map(key => obj[key]) // returns an array of values --> ["value1", "value2", "value3"]
Object.keys(obj).map(key => {
console.log(obj[key])
})
// logs all values one by one --> "value1" "value2" "value3"
JS ES5 answer:
Object.keys(obj).map(function(key) {
console.log(obj[key])
});
Related
I'm using rxjs map to retrive data in firestore like this:
getArtists(): Observable<DocumentData> {
const users$ = this.firestore.collection('/Users').get()
users$.subscribe((users) => {
users.docs.map(user => user.data().artistName !== "" && user.data().role === 'ARTIST')
});
return users$;
}
but when i'm getting value like this :
this.userService.getArtists().subscribe(
(userDocs) => {
userDocs.docs.map((user) => {
this.artists.push(user.data());
console.log(this.artists)
this.record = this.artists.length;
})
});
it's return always the user when the artistName is equals to "" and role is not equals to 'ARTIST'.
why ?
thank's everybody!
you need to map data in a map operator instead of a subscription and return a value in as a pipe.
Unfortunately, in your code isn't clear what and when you want to filter, why a user is in users.docs when it tend to be a doc.
Please check an example below and consider updating your question with more info.
import {filter, map} from 'rxjs/opreators';
getArtists(): Observable<DocumentData> {
return this.firestore.collection('/Users').get().pipe( // <- use pipe
map(users => {
// here some changes in users if we need.
return users;
}),
),
filter(users => {
returns true; // or false if we don't want to emit this value.
}),
}
I have an array of dictionaries I would like to populate in a list view with SwiftUI.
I used for loops in the past but since that's not possible within a View I'm stuck as to what to do. I'm able to achieve partial results with the code below.
struct Test : View {
let dict = csvArray[0]
var body: some View {
let keys = dict.map{$0.key}
let values = dict.map {$0.value}
return List {
ForEach(keys.indices) {index in
HStack {
Text(keys[index])
Text("\(values[index])")
}
}
}
}
}
I'm looking to index through the entire Array of dictionaries and append them to the list, not just csvArray[0].
This is like Sections of key values, right?
So do it like:
This is an example of csvArray, This could be anything but you should update the rest of the code duo to the original data type
let csvArray = [
[ "section0-key0": "section0-value0",
"section0-key1": "section0-value1"],
[ "section1-key0": "section1-value0",
"section1-key1": "section1-value1"],
[ "section2-key0": "section2-value0",
"section2-key1": "section2-value1"]
]
This is your code for a single dictionary. but this will take that dictionary instead of hardcoded one:
struct SectionView : View {
#State var dict = [String: String]()
var body: some View {
let keys = dict.map{$0.key}
let values = dict.map {$0.value}
return ForEach(keys.indices) {index in
HStack {
Text(keys[index])
Text("\(values[index])")
}
}
}
}
And this is the list builder connected to the original array. I used sections for the meaningfulness of the data structure.
struct ContentView: View {
var body: some View {
List {
ForEach(csvArray, id:\.self) { dict in
Section {
SectionView(dict: dict)
}
}
}
}
}
Note that you can't relay on the order of the key value in a dictionary. So I suggest you to do some sorting before populating the list or use another data structure like class or struct instead of a plain dictionary.
I have a Map that looks like this
{
title: "Hello world",
images: [
{ url: "http://example.com/image1" },
{ url: "http://example.com/image2" },
{ url: "http://example.com/image3" }
]
}
and I need a List<String> of the images that looks like this
[
"http://example.com/image1",
"http://example.com/image2",
"http://example.com/image3"
]
My current code looks like this
List<String> images = [];
if( map['images'] is List<dynamic> ) {
map['images'].forEach((v) {
if (null != v['url'])
images.add(v['url']);
});
}
It works good, but I am curious if there is a one-liner that would accomplish the same thing in a neat (and error safe) way?
var list = map['images'].map((innerMap) => innerMap['url']).toList()
I guess you are looking for something like this:
var images = map['images'].where((m) => m['url'] != null).map((value) => value['url']).toList();
First we select all the items from map that do not contain a null field for url. Then we map these url values to a new List.
I have a data structure which have multiple nested keys, key1 and key2.
The value of key1 and key2 is unknown and will typically be some GUID's.
How do I get the data out of this structure?
"key1":
{
"key2": {
"name1":"value1",
"name2":"value2",
"sub1":
{
"sub1_name1":"sub1_value1",
"sub2_name2":"sub2_value2"
},
"name3":"value3"
}
}, .... more records following
I have the following code that extracts some data but after that I am unable to query the data:
admin.database().ref('table_x/').once('value', (snapshot) => {
console.log(snapshot.key); //table_x
snapshot.forEach(function(child) {
var key1 = child.key; // this gives key1
// get key 2
// get key 2's values, children
Something like this?
for (key in child) {
for (innerkey in child[key]) {
console.log(innerkey);
}
}
https://jsfiddle.net/chickenbeef/ycers98g
Use the library Defiantjs(http://defiantjs.com/) they have a nice implementation of an xslt template to pull in your data set
once you able to loop through your data structure, use the xpath tool provided by the library to run specific queries.
Example of JSON.search
data = [{
"key1": {
"key2": {
"name1": "value1",
"name2": "value2",
"sub1": {
"sub1_name1": "sub1_value1",
"sub2_name2": "sub2_value2"
},
"name3": "value3"
}
}}],
res1 = JSON.search(data, "//*[contains(name(), 'key')]/."),
res2 = JSON.search(data, "//*[contains(text(), 'sub')]/..");
https://jsfiddle.net/edsonvanwyk/amanp3g0/4/
I’m having issues getting two dependant types of data from a PouchDB database.
I have a list of cars that I get like so:
localDB.query(function(doc) {
if (doc.type === ‘list’) {
emit(doc);
}
}, {include_docs : true}).then(function(response) {
console.log(“cars”, response);
// Save Cars List to app
for(var i = 0; i < response.rows.length; i++) {
addToCarsList(response.rows[i].id, response.rows[i].carNumber);
}
console.log(“Cars List: " + carsListToString());
return response;
}).then(function(listRecord) {
listRecord.rows.forEach(function(element, index){
console.log(index + ' -> ', element);
localDB.query(function(doc) {
console.log("filtering with carNb = " + element.carNb);
if (doc.type === 'defect' && doc.listId == getCurrentListId() && doc.carNb == element.carNb ) {
emit(doc);
}
}, {include_docs : false}).then(function(result){
console.log("defects", result);
}).catch(function(err){
console.log("an error has occurred", err);
});
});
}).catch(function(err) {
console.log('error', err);
});
Here's what happens. After getting the list of cars, then for each cars I would like to query the defects and store then in some arrays. Then when all that querying is done, I want to build the UI with the data saved.
But what's happening is that the forEach gets processed quickly and does not wait for the inner async'd localDb.query.
How can I query some documents based on an attribute from a parent query? I looked into promises in the PouchDB doc but I can't understand how to do it.
(please forget about curly quotes and possible lint errors, this code was anonymized by hand and ultra simplified)
The method you are looking for is Promise.all() (execute all promises and return when done).
However, your query is already pretty inefficient. It would be better to create a persistent index, otherwise it has to do a full database scan for every query() (!). You can read up on the PouchDB query guide for details.
I would recommend installing the pouchdb-upsert plugin and then doing:
// helper method
function createDesignDoc(name, mapFunction) {
var ddoc = {
_id: '_design/' + name,
views: {}
};
ddoc.views[name] = { map: mapFunction.toString() };
return ddoc;
}
localDB.putIfNotExists(createDesignDoc('my_index', function (doc) {
emit([doc.type, doc.listId, doc.carNb]);
})).then(function () {
// find all docs with type 'list'
return localDB.query('my_index', {
startkey: ['list'],
endkey: ['list', {}],
include_docs: true
});
}).then(function (response) {
console.log("cars", response);
// Save Cars List to app
for(var i = 0; i < response.rows.length; i++) {
addToCarsList(response.rows[i].id, response.rows[i].carNumber);
}
console.log("Cars List: " + carsListToString());
return response;
}).then(function (listRecord) {
return PouchDB.utils.Promise.all(listRecord.rows.map(function (row) {
// find all docs with the given type, listId, carNb
return localDB.query('my_index', {
key: ['defect', getCurrentListId(), row.doc.carNb],
include_docs: true
});
}));
}).then(function (finalResults) {
console.log(finalResults);
}).catch(function(err){
console.log("an error has occurred", err);
});
I'm using a few tricks here:
emit [doc.type, doc.listId, doc.carNb], which allows us to query by type or by type+listId+carNb.
when querying for just the type, we can do {startkey: ['list'], endkey: ['list', {}]}, which matches just those with the type "list" because {} is the "higher" than strings in CouchDB object collation order.
PouchDB.utils.Promise is a "hidden" API, but it's pretty safe to use if you ask me. It's unlikely we'll change it.
Edit Another option is to use the new pouchdb-find plugin, which offers a simplified query API designed to replace the existing map/reduce query() API.
Another approach would be to pull both the list docs and the defect docs down at the same time then merge them together using a reduce like method that will convert them into an array of objects:
{
_id: 1,
type: 'list',
...
defects: [{
type: 'defect'
listId: 1
...
}]
}
By pulling the list and the defects down in one call you save a several calls to the pouchdb query engine, but you do have to iterate through every result to build your collection of lists objects with and embedded array of defects.
// This is untested code so it may not work, but you should get the idea
var _ = require('underscore');
// order documents results by list then defect
var view = function (doc) {
if (doc.type === 'list') {
emit([doc._id, doc.carNumber, 1);
} else if (doc.type === 'defect') {
emit([doc.listId, doc.carNb, 2])
}
}
localDB.query(view, { include_docs: true })
.then(function(response) {
return _(response.rows)
.reduce(function(m, r) {
if (r.key[2] === 1) {
// initialize
r.doc.defects = [];
m.push(r.doc)
return m;
}
if (r.key[2] === 2) {
var list = _(m).last()
if (list._id === r.key[0] && list.carNumber === r.key[1]) {
list.defects.push(r.doc);
}
return m;
}
}, []);
})
.then(function(lists) {
// bind to UI
});
With couch, we found reducing calls to the couch engine to be more performant, but I don't know if this approach is better for PouchDB, but this should work as a solution, especially if you are wanting to embed several collections into one list document.