KnockoutJS: How to quickly turn observables back into values - arrays

I currently have a observable array of objects which inside of those have observable properties.
appViewModel.diceArray = ko.observableArray( [ {
diceAmount: ko.observable(1),
diceType: ko.observable(null),
diceAddition: ko.observable(0),
diceMultiplication: ko.observable(1)
} ] );
I am now looking to save the data to a database, and so need my array of objects (without them being observable). Is there a quicker method than looping through the array and manually creating objects?

Use ko.toJS
From http://knockoutjs.com/documentation/json-data.html
ko.toJS — this clones your view model’s object graph, substituting for each observable the current value of that observable, so you get a plain copy that contains only your data and no Knockout-related artifacts

If the potatopeelings' answer is not what you want. You can use the ko.utilsArrayMap:
var dices = ko.utils.arrayMap(appViewModel.diceArray, function(dice) {
return { diceAmount: dice.diceAmount(),
diceType: dice.diceType(),
diceAddition: dice.diceAddition(),
diceMultiplication: dice.diceMultiplication()
}
});
//do something with dices

ko.toJS is also available as an industrial strength mapping plugin which also supports going the other way, which you are going to need.

Related

Updating Array of Objects in Firebase Realtime Database in React js

I have a problem with updating certain properties of an array of objects in a real-time database in Firebase.
My object looks like the following (see picture).
Now I want to update the IsComing property of the second participant object.
At the moment I use the updateIsComming() function, but this is not very convincing, because I have to rewrite the whole object.
function updateIsComming() {
const db = getDatabase();
update(ref(db, " your_path/EventModel/" + modelkey ), {
Location: "London",
Participants: [
{ Name: "Bella2", IsComming: "true" },
{ Name: "Tom", IsComing: "true" },
],
});
Instead, I just want to reference the specific prop from that array. For example
Participant[1].IsComming = false;
Is there any way I can access a specific array of an object directly.
Arrays as a data structure are not recommended in Firebase Realtime Database. To learn why, I recommend reading Best Practices: Arrays in Firebase.
One of the reasons for this is that you need to read the array to determine the index of the item to update. The pattern is:
Read the array from the database.
Update the necessary item(s) in the array in your application code.
Write the updated array back to the database.
As you already discovered, this is not ideal. As is common on NoSQL databases, consider an alternative data structure that better suits the use-case.
In this case, an alternative data structure to consider is:
Participants: {
"Bella2": true,
"Tom": true
}
In there, we use the name of the participant as the key which means:
Each participant can be present in the object only once, because keys in an object are by definition unique.
You can now update a user's status by their name with: update(db, "your_path/EventModel/" + modelkey + "/Participants/Tom", false).

react facing issues to find out specific data from an array of objects

I have a few collections of data that are in JSON format and want to access specific data conditional data, an example I want to access which one has teacher:true and put it in a state.
I have tried it with conditions inside the loop and filter function.
[
0:{name:"Rou",id:"121"}
1:{name:"Sou",id:"122",teacher:"true"}
2:{name:"Tou",id:"123"}
3:{name:"Vou",id:"124",teacher:"true"}
4:{name:"Kou",id:"125",teacher:"false"}
5:{name:"Wou",id:"126"}
]
here I want to get only
1:{name:"Sou",id:"122",teacher:"true"}
3:{name:"Vou",id:"124",teacher:"true"}
which means only where the teacher is true.
This has nothing to do with react. It's a javascript array problem.
let people = [
{name:"Rou",id:"121"},
{name:"Sou",id:"122",teacher:"true"},
{name:"Tou",id:"123"},
{name:"Vou",id:"124",teacher:"true"},
{name:"Kou",id:"125",teacher:"false"},
{name:"Wou",id:"126"}
];
let teachers = people.filter((person) => person.teacher == "true");
Note that you need it's strongly recommended to use a boolean type instead of a string:
// Strongly discouraged
{name:"Sou",id:"122",teacher:"true"};
// Better
{name:"Sou",id:"122",teacher: true};

ng2-smart-table display list of object

Is there a way to display a list of objects in a single table cell for ng2-smart-table? I have tried creating a renderComponent but I am getting an empty value. Another question is will the filtering and sorting still work for this?
As I understood , You have a object and you want to display that data in ng2-smart-table.
For that follow this step.
import { LocalDataSource } from 'ng2-smart-table';
source : any = LocalDataSource;
When you call API then you have to set that data in source.
this.apiService.POST({}, 'getProductList').subscribe((res) => {
console.log(res);
this.source = new LocalDataSource(res.data); // Set response as per your res.
});
As you can see I have also set one array and that array has objects of data and I have set in table.
I hope this may help you. :)

Query arrays values with Firebase

Is there any way to on Firebae to filter data in an array?
I have this model on my Firebase:
-KABIGeWnBMUKjLTcvp8
deviceToken:"7DE60240CB4B712F05A009F32358610C1327917E7E68409..."
favorites
0:"Masha"
1:"moksha"
name:"juan"
And the problem is that I can't find any method to get all "users" that contain a certain value on the "favorites" array field.
Nope, that's not an option See firebase equivalent to sql where in ().
Instead: invert your data structure to make this query possible:
items_by_favorites
"Masha"
"-KABIGeWnBMUKjLTcvp8"
"moksha"
"-KABIGeWnBMUKjLTcvp8"
Now you can look up the item keys for Masha with a simple read: ref.child('items_by_favorites/Masha') and then load each item:
ref.child('items_by_favorites/Masha').on('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
ref.child('items').child(key).once('value', function(itemSnapshot) {
console.log(itemSnapshot.val());
});
});
})
First of all your question is answered deep in the guide for retrieving data, which is where I got this answer. It's under complex queries, then range queries, should you want more info.
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").equalTo(25).on("child_added", function(snapshot) {
console.log(snapshot.key());
});
The basic idea is that you need to first order the reference by a common child value, and then call .equalTo() to end up with a query that yields what you want.
Also you can call order by child like
ref.orderByChild("height/sublevel")
To drill deeper in the tree.
FirebaseFirestore.instance.collection('your collection name').where('favorite', arrayContains: 'Masha').snapshot();

Why does the backbone.js where function return an array of models?

When I use the Backbone.Collection.where function to filter the collection I get an array of models as return value but not an other filtered collection object. So I can't use other collection functions with that.
What is the purpose of such behavior?
where isn't the only method that returns an Array. where returns a new Array because you definitely don't want it mutating your existing Collection automatically. Also, many times you may want the result in Array form.
For whatever reason, the BB devs decided that it was better to return a new Array rather than a new Collection. One thought could be that, perhaps the returned data would be used in a different type of Collection. Another reason could be so that you always know what is returned from one of these methods. 2+ types of collections will ALWAYS return Arrays from these types of methods rather than having to try and inspect via instanceof or something else that isn't very reliable.
Edit
In addition, you COULD make your collections behave in a manner where you return new Collections. Create a base Collection to do something like this:
// Override the following methods
var override = ["where","find",...];
var collectionProto = Backbone.Collection.prototype;
BaseCollection = Backbone.Collection.extend({});
for (var key in collectionProto) {
if (collectionProto.hasOwnProperty(key) && override.indexOf(key) > -1) {
BaseCollection.prototype[key] = function () {
return new this.constructor(collectionProto[key].apply(this, arguments);
};
}
}
Instead over extending off Backbone.Collection, extend off BaseCollection.
Note that you can still use most of the underscore utilities on arrays. Here's how to use each() after a filter()
_.each( MyCollection.filter( filter_fn() {} ), each_fn() {} )

Resources