I have the following observable
#observable private _nodes: ValidNode[] = [];
how can I turn it into a simple array, by doing
this._nodes.slice();
.slice() is totally fine to convert observable array back to plain JS array.
There is also mobx.toJS() util function, which can convert any observable data to plain JS format, it also works recursively.
More in the docs
Related
I am using the new Nuxt3 composable useAsyncData to fetch a large csv file.
In the setup function I use the useAsyncData to pull the data ( d3.csv is a sort of fetch function)
const { data } = await useAsyncData(() =>
d3.csv(url)
)
Then I return the data from the setup function. I use it in the other methods of the component (which is written in the traditional Vue options API).
When I observe the data object in the chrome dev tools, it is a ref or a reactive proxy. The thing is that I don't want to have such a large reactive object, because it is not going to change.
How can I return the raw object instead of the reactive version? Is it possible?
Thanks!
I have the following code fragment and would like to strip the observer functionality from the user.accounts object. How would I do that? this.$cookies is a reference to my vue-cookies instance
setUserAccount(user, account){
// var accounts = Object.assign({},user.accounts)
this.$cookies.set('AUTH_TOKEN', user.authHash);
this.$cookies.set('CURRENT_ACCOUNT', user.id);
this.$cookies.set('ACCOUNTS', user.accounts);
console.log(user.accounts);
},
Convert the object to a JSON string. That will remove all the Vue observer mechanisms.
const strAccounts = JSON.stringify(user.accounts)
this.$cookies.set('ACCOUNTS', strAccounts);
And to convert it back (without the observer functionality).
JSON.parse(strAccounts);
The only caveat is you need to watch out for circular references in your object, and functions will not get serialized.
I was learning mongoose, and I am trying to figure out.
Why toObject() was needed to convert the data received into Object, when it was already in object form it seems
Here is the code:
UserSchema.methods.toJSON = function() {
var user = this;
var userObject = user.toObject();
return _.pick(userObject, ['_id', 'email']);
};
I cannot understand why toObject() was used to extract the meaningful properties from the object.
Thanks
toObject is a mongoose document method Document.prototype.toObject() which:
Converts this document into a plain javascript object, ready for storage in MongoDB.
You can more about it here
The reason it is called there is because a plain JS object is required in order to do the lodash _.pick which would create a new object with only _id and email properties.
In my component I am trying to get the old value and new value of a particular array of objects that is assigned in the vuex store state as followed. However when I newArray and oldArray return the same array of objects.
I understand from the documentation the following but I dont understand what is the best way to retrieve the different versions.
Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.
here how I am trying to do it right now in the component
export default {
name: 'O1_OrderBook',
watch: {
'$store.state.orderBookSell': {
deep: true,
handler (newArray, oldArray) {
console.log(newArray,oldArray)
}
}
},
}
let say when you create an array/object in Javascript,
var arr = [1,2,3];
This creates an array in the browser's memory. But what arr variable contains is not the entire array value, it contains the reference to the array in browser memory. You could think of it as arr contains an address that can point you to the real array value in browser's memory.
if you do
var arr = [1,2,3];
var arr2 = arr;
arr2[0] = 4;
console.log(arr); // you would get [4,2,3];
editing arr2 changed arr too. Because they both point to the same array in browser memory.
That's what "the old value will be the same as the new value because they reference the same Object/Array" means.
The same principle applies to object as well. In Javascript, an array is just a special type of object.
to retrieve the different versions of the array in the watcher, you must clone it to set it as a new array everytime you mutate it.
for e.g.,
state.orderBookSell = [...state.orderBookSell];
BUT..... [...array] is shallow cloning, not deep cloning. And that's a problem. You have an array of objects. Remember that object also have the same rules. They are passed by reference. So you gotta do a deep clone, so that all the objects is cloned as well.
using lodash cloneDeep method for deep cloning
state.orderBookSell = _.cloneDeep(state.orderBookSell);
Based on Jacobs answer this is what I re-arranged in my component as to get it to work.
I created a computed variable in the component that deepClones the particular state array of objects.
computed: {
orders () {
return _.cloneDeep(this.$store.state.theArray)
},
},
and then setup a watch for that computed variable
watch: {
orders (newValue,oldValue) {
console.log(newValue,oldValue)
}
}
I use Jackson to generate a JSON formatted String from Java objects.
The generated JSON string is then sent in a HTTPResponse and Highcharts interprets it client-side to display a chart.
It was all fine until I found out I need to serialize a JavaScript function. E.g
"xAxis" : {
events {
setExtremes: function(event) {
//javascript code
}
}
}
I'm aware this is not valid JSON anymore but I need a workaround.
Any ideas on how to do this?
Although I know nothing about jackson, I had a similar problem doing this in a java json library.
What did was put a placeholder value where I wanted the function to go:
setExtremes: "SETEXTREMES_PLACEHOLDER"
Then when I had converted the json object to a json string, I did a string replace operation on the placeholder with the required function.
Not pretty, but it did the job.