Stringify and parse an object literal - javascript

I have this object literal
var rides = {
brand: {
type: String,
label: "搜尋",
max: 100
},
model: {
type: String,
label: "Tìm kiếm",
max: 100
},
fueltype: {
type: String,
label: "Пошук",
allowedValues: ['Petrol', 'Diesel', 'Hybrid', 'Electric'],
},
bodystyle: {
type: String,
label: "بحث",
allowedValues: ['Convertibles', 'Coupes', 'Hatchbacks', 'Vans', 'Sedans', 'Suvs', 'Trucks', 'Wagons'],
optional: true
},
topspeed: {
type: Number,
label: "חיפוש",
optional: true
},
power: {
type: Number,
label: "Power (HP)",
optional: true
}
};
which i have stringfied in this way
var ss = JSON.stringify(rides);
However, for what I am doing to work, I need to get the object i stringfied exactly the way it was before i stringfied
Thi is what it looks like https://jsfiddle.net/y37crsvd/1/
Object { brand: Object, model: Object, fueltype: Object, bodystyle: Object, topspeed: Object, power: Object }
How can I stringify the object literal so as to show the nested object properties?

You can't stringify() functions, unless you use a custom revive parameter on JSON.parse(), and a custom mapper parameter on JSON.stringify(). Or, define Function.prototype.toJSON to get the "plain" JSON.stringify() to work with functions like window.Number and window.String.

The xx in the fiddle does contain the nested object properties, it's the console which requires you to expand the inner properties as well...

When you log xx the console shows the object and allow you to expand the properties. It also puts the properties in alphabetic order.
If you do a JSON.stringify(xx) you will see exactly the same string as you input in the first time (properties in the same order...).

Related

How to get properties of nested objects with ng-multiselect-dropdown

I'm trying to use the ng-multiselect-dropdown https://www.npmjs.com/package/ng-multiselect-dropdown. I've got an array, that contains nested objects. The structure looks some kind like this:
obj1: {
id: string;
atr1: {
atr2: string;
atr3: string;
}
}
My question:
How can I display for example atr2 in the dropdown-menu? This is my dropdown-setting:
dropdownSettingsProjectManagers: any = {
singleSelection: false,
idField: 'id',
textField: 'atr1.atr2', //? What do I have to put in here?
showSelectedItemsAtTop: true,
clearSearchFilter: true,
allowSearchFilter: true,
enableCheckAll: false,
allowRemoteDataSearch: true
};
Thanks, for every help.

Why "duplicate key error" when inserting subdocument arrays?

I have a Mongoose Schema in which I use subdocuments. Their definitions are:
const vraagSchema = new mongoose.Schema({
vraagNummer: {
type: Number,
required: true,
min: 1
},
vraagTekst: {
type: String,
minLength: 1,
required: true
},
waarde: {
type: Number,
required: true,
min: 1
}
}, { collection: 'vragen' });
const checkSchema = new mongoose.Schema({
checkID: {
type: String,
required: true,
min: 2
},
sessieNummer: {
type: Number,
required: true,
min: 1
},
omschrijving: {
type: String,
required: true
},
vragen: {
type: [vraagSchema]
},
logData: {
type: String,
required: false,
default: ''
}
});
checkSchema.index({ sessieNummer: 1, checkID: 1 }, { unique: true })
Now, when I insert 1 Check item with an empty array for the "vragen" field ("vragen" is Dutch for "questions"), there is no problem.
But when I try to insert another Check item, with slightly different field values (so that it is unique), but also with an empty array "[]" as value for "vragen", I get an error: "MongoError: E11000 duplicate key error collection: demastermind_test.checks index: vragen.vraagNummer_1 dup key: { : null }".
Why is an empty array leading to a duplicate key error? And how can I prevent this?
I then checked what happened if I inserted Check items with non-empty arrays. So I inserted two checks with different field values (so they are unique), where 1 item has a "vragen" array with on "vraag" item in it, and 1 item has a "vragen" array with two "vraag" items in them (where I made sure that the two items had different "vraagNummer" waardes).
And that also leads to the exact same duplicate key error.
What am I missing?
I got this problem fixed. Apparently somewhere when I started working on this, I used an incorrect schema definition (or something), and that error got 'stuck' in de Collection.
I solved the problem by deleting the whole Collection (it currently is a test collection, so that wasn't a problem), and now it works as it should be.

Is it possible to use Proptypes for an associative array of complex objects

Here is an example of the given structure I am looking for
const fields = {
["NAME"]: {isSet: false, display: "Customer Name", required: true},
["PHONE"]: {isSet: false, display: "Customer Phone", required: true},
["LOCATION_ID"]: {isSet: false, display: "Location ID", required: true},
["EMPLOYEE_ID"]: {isSet: false, display: "Employee ID", required: false},
["CUSTOMER_EMAIL"]: {isSet: false, display: "Customer Email", required: false},
["EMPLOYEE_EMAIL"]: {isSet: false, display: "Employee Email", required: false}
};
The key can be any string value and that value should be an object with isSet, display, required
Is this even possible or do I have to write a custom validator?
Header.propTypes = {
fields: propTypes.arrayOf(propTypes.shape({
..... ?
})).isRequired
};
First thing to note here is you can't use PropTypes.arrayOf since your structure is an object, not an array. You would need to use PropTypes.shape, but as you guessed, you can only do this with a custom validator.
If you check the source code for the shape validator, you'll see that it returns a function that loops over the keys of the object you pass it and runs the validator you passed along each key. Which is to say, you need to pass an object with explicit key names, which could be variables, but you can't give it a placeholder.
However, if your data structure was really an array, you could do the following:
Header.propTypes = {
fields: PropTypes.arrayOf(PropTypes.shape({
isSet: PropTypes.bool.isRequired,
display: PropTypes.string.isRequired,
required: PropTypes.bool.isRequired
)).isRequired
}
Otherwise you're going to have to write a custom validator, which is a function that receives props, propName and componentName, and returns an Error object if the prop you're given doesn't satisfy the condition you want.

How can I deserialize a json string without knowing the name of the fields?

I have a string that can look like this:
[
{
Id:{
editable:false,
nullable:true
}
},
{
Product:{
validation:{
required:true
}
}
},
{
Cost:{
type:"number",
validation:{
required:true
}
}
}
]
It can also look like this:
[
{
Id:{
editable:false,
nullable:true
}
},
{
Car:{
validation:{
required:true
}
}
},
{
Make:{
validation:{
required:true
}
}
}
]
The point is that the string will always have an Id field with some predictable values, but additional fields can be named anything.
I have some javascript which I need to look like this:
schema: {
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
Product: { validation: { required: true } },
Cost: { type: "number", validation: { required: true }}
}
}
}
... where the content of fields needs to correlate the string.
Currently I have an ajax call that get some other data my code needs and I would like to also give it the results I need for the fields. I would like to replace the json like so:
schema: {
model: {
id: "Id",
fields: ajaxResult.fields
}
}
}
The normal route is to create a class (or classes) to which I can deserialize the json string, but in this case the fields in the json string can be completely arbitrary. So I cannot create classes for this since I don't know what the properties will be called.
How can I deserialize this string so when I return it from my Action it will work as I describe?
Currently my controller action looks something like this:
public IActionResult GetJsonData(Guid id)
{
var model = new GridDataModel
{
schema = SchemaToJson(id),
//fields = FieldsToJson(id),
gridData = RowsToJson(id)
};
return Json(model);
}
In Visual Studio 2015, you can use the "paste special" function, Visual studio will generate all classes (including nested classes etc.) for you, no single line of your own coding is needed:
See animations below: (original GIF is from here.)

Cannot load data in an ExtJS gridpanel with loadData()

I need to periodically add new data in the grid's store. The store is defined by the following code:
this.reader = new Ext.data.JsonReader({
idProperty: 'id',
fields: this.lesFields
});
this.ds = new Ext.data.GroupingStore({
reader: this.reader,
data: this.leData,
sortInfo: {field: 'dendisc', direction: 'ASC'},
groupField: 'categorie'
});
When I need to append some new data, I do this using this.getStore().loadData(this.leData). Technically the data does appear in the grid's store, but I see on the display only zeros (in the int fields) and blank strings (in the string fields). I did some researches in Chrome's console and I found out that the data property and the json property are not the same in this.getStore().data. In json there is the array with valid data, but in data there are only zeros and blank strings.
Am I missing something? Would the handleAs:'json' property save the situation?
JsonReader requires root to be defined. root points the sub-property which contains the records.
here a sample taken from ext documentation:
var myReader = new Ext.data.JsonReader({
idProperty: 'id'
root: 'rows',
totalProperty: 'totalRows',
fields: [
{name: 'id' },
{name: 'name' }
]
});
and a sample data to be read:
{
success: true,
totalRows: 100,
rows: [ // root
{ id: 1, name: 'Alf' },
{ id: 2, name: 'Ben' },
{ id: 3, name: 'Cod' },
...
]
}
I am not that used to GroupingStores but I think the Reader expect a json object like { Id:0, Name: 'MyName' } or a Array of such objects and then try to match them against the registered fieldnames. But I don't know what there is in your arrays so this is just a guess

Categories

Resources