How to parse specific object in angular or javascript? - javascript

How are we going to parse following type of object in angular or javascript, maybe using for search loop or parsing?
I wanted to get the title value and assign it to title because as you can see the value of title is object:
{'title': 'Hey', 'instruction': 'Take a sad song a…75, 'sub_title': 'Jude', 'timelimit': '01:05:01'}
instead of "Hey" as you can see on the example (same also with the second object). Is there a way we can do that?
JSON array of objects format:
[
{
id:0,
title:"{'title': 'Hey', 'instruction': 'Take a sad song a…75, 'sub_title': 'Jude', 'timelimit': '01:05:01'}"
},
{
id:1,
title:"{'title': 'Assessment', 'instruction': 'Jude', 'cr…71, 'sub_title': 'Test', 'timelimit': '06:25:08'}"
}
]
Desired output:
[
{
id:0,
title:"Hey"
},
{
id:1,
title:"Assessment"
}
]

Make sure your have the correct format in json - double quotation marks inside and single outside.
Like this
'{"title": "Hey", "instruction": "Take a sad song a…75", "sub_title": "Jude", "timelimit": "01:05:01"}'
Then you can simply do.
let jsonString = '{"title": "Hey", "instruction": "Take a sad song a…75", "sub_title": "Jude", "timelimit": "01:05:01"}';
let title = JSON.parse(jsonString).title;
console.log(title);

var jsonObj = [
{
id:0,
title:"{'title': 'Hey', 'instruction': 'Take a sad song a…75, 'sub_title': 'Jude', 'timelimit': '01:05:01'}"
},
{
id:1,
title:"{'title': 'Assessment', 'instruction': 'Jude', 'cr…71, 'sub_title': 'Test', 'timelimit': '06:25:08'}"
}
];
var updatedJsonObj = jsonObj.map( obj => {
return {
...obj,
title: JSON.parse(obj.title).title
}
});
console.log(updatedJsonObj);
//updatedJsonObj will have your required format

Here we are doing following steps
Iterate over array
For each object, title field is not valid JSON. make it valid by using title.replace(/'/g, '"'). Then Parse JSON.
Then assign title of parsed JSON to title of object
Here is the code
arr = [
{
id:0,
title:"{'title': 'Hey', 'instruction': 'Take a sad song a…75', 'sub_title': 'Jude', 'timelimit': '01:05:01'}"
},
{
id:1,
title:"{'title': 'Assessment', 'instruction': 'Jude', 'sub_title': 'Test', 'timelimit': '06:25:08'}"
}
]
arr = arr.map((e)=> { e.title = JSON.parse(e.title.replace(/'/g, '"')).title; return e; })
// expected result is in arr
.

As others have stated your json is not valid but since you have mentioned that it is what you get from your backend and you cannot change it, I suggest treat your title as string and use string operations to get the desired value.
for example you can use the following to get ID and title
<div ng-repeat="item in data">
{{item.id}} -
{{item.title.split('\'')[3]}}
</div>
Demo

Related

JS: Extracting data from an array of objects

I have a complex query with 100s of fields and nested fields. What I want to do is, for each Index, extract the English and French text. As you can see in the array, there is no French text for some indexes. In that case I want to get the English text.
For me extracting the English text works fine because the text is already there, but incase of French, I get undefined errors. What would be the best way to implement this. Is Loadash needed for this or just pure JS methods?
Just to be clear, I have erros with extracting french because in some fields, french text is not available, I want to use the english value in that case.
Also It is recommend if I am able to get the English and French values by it's language field rather than the index. I have no idea how to do that.
Any suggestion, documentation is appreciated. Thank you!
example array:
[
{
id: "1",
name: [
{
language: "en-US",
text: "HOLIDAY"
}
],
order: 6,
Groups: [
{
name: [
{
language: "en-US",
text: "REGULAR"
}
],
code: "REGEARN"
},
{
name: [
{
language: "en-US",
text: "CHARGE"
}
],
code: "CHARGE"
}
]
}
]
and here is the code sandbox that reproduces my error:
CODE SAND BOX
https://codesandbox.io/s/javascript-forked-5073j
EDIT:
EXPECTED OUTPUT:
{
key: key,
englishtext: "Value Here",
frenchtext: "Value Here"
}
below is a working code, but issue is it does not work when there is no french language or that field. I get undefined errors. So is it possible I can get the needed data from the language field?
x.map((y) => ({
key: y.id,
name: y.name[0].text,
groupname: y.Groups ? x.Groups[0].name?.[0].text : 'N/A',
}))
Do you expect result like this? If you don't mind lodash.
const _ = require('lodash');
const getNames = (arr) => {
return arr.map((obj) => {
const id = obj.id;
const englishtext = _.get(obj, 'name[0].text', 'N/A');
const frenchtext = _.get(obj, 'name[1].text', englishtext);
return { id, englishtext, frenchtext };
});
};
console.log(getNames(x));
// [
// { id: '1', englishtext: 'HOLIDAY', frenchtext: 'HOLIDAY' },
// { id: '2', englishtext: 'Stat Holiday', frenchtext: 'Congé Férié' },
// { id: '3', englishtext: 'Over', frenchtext: 'Over' }
// ]

How to Combine/merge two arrays in similar index of post request in node.js/express and convert in object to insert mongoose model

I have a page that gets two arrays of input elements and sends them by post request to my app.js:
<input type="text" name="titleAttr[]" > </input>
<input type="text" name="descriptionAttr[]"> </input>
I created a Schema that receives an array with 2 fields, titleAttr and descriptionAttr, which correspond to the <input> elements above:
const mySchema = mongoose.Schema({
titulo: String,
attrs: [{
titleAttr: String,
descriptionAttr: String
}]
});
I can insert the data manually and it works:
MyModel.bulkWrite([ { insertOne : { document: {
title : "TEST",
attrs: [
{titleAttr : "test 1", descriptionAttr: "This is a test 1"},
{titleAttr: "test 2", descriptionAttr: "This is another test"}
]
} } }
]);
Here is a screenshot of the form .
When the post request is sent from my form and I print it in app.js, I get these results:
console.log(req.body.titleAttr); //result: [ 'test 1', 'test 2' ]
console.log(req.body.descriptionAttr);// result: [ 'This is a test 1', 'This is another test' ]
This code doesn't work:
ConceitoHTML.bulkWrite([ { insertOne : { document: {
titulo : req.body.title,
attrs: [
{
titleAttr: req.body.titleAttr,
descriptionAttr: req.body.descriptionAttr
}
]
} } } ]);
I want to merge my two arrays and insert into MongoDB as an array of objects. How do I generate an array like the following?
const myArray = [
{
titleAttr: req.body.titleAttr[0],
descriptionAttr: req.body.descriptionAttr[0]
},
{
titleAttr: req.body.titleAttr[1],
descriptionAttr: req.body.descriptionAttr[1]
}
]
You can do it with this code below 👇 to get an array as expected what you want:
const {titleAttr, descriptionAttr} = req.body;
const myArray = [];
// check the length first, make sure it's same
if(titleAttr.length === descriptionAttr.length) {
for(let i=0; i<titleAttr.length; i++) {
myArray.push({ titleAttr: titleAttr[i], descriptionAttr: descriptionAttr[i] })
}
}
console.log(myArray); // this is the array result
I hope it's can help you.

Angularjs splice array of objects inside of an object always removes last object

I have an object which contains an array of objects called "blocks":
$scope.microsite = {
images: [
{url: "https://unsplash.it/800/400/?image=20"},
{url: "https://unsplash.it/800/400/?image=15"},
{url: "https://unsplash.it/800/400/?image=52"}
],
blocks: []
};
When I add stuff to this array, it behaves perfectly normally:
$scope.addElement = function(a){
if(a=='heroslider'){
var data = {
slides: [
{
id:0,
image:0,
title: "Title",
desc: "Description",
},
{
id:1,
image:1,
title: "Title",
desc: "Description",
},
{
id:2,
image:2,
title: "Title",
desc: "Description",
}
]
};
} else if(a=='threecol'){
var data = {
columns: [
{
title: "Column one",
text: "This is a column for features",
},
{
title: "Column two",
text: "This is a column for features",
}
]
};
}
var element = {
template: a,
data: data
};
$scope.microsite.blocks.push(element);
}
However when I try to remove an object from the array by calling this function on ng-click and passing in the object from an ng-repeat...
$scope.removeElement = function(element){
var x = $scope.microsite.blocks.indexOf(element);
console.log($scope.microsite.blocks[x]);
console.log(x);
$scope.microsite.blocks.splice(x, 1);
}
I am able to get both the correct object and the correct index in my console, but when it goes to splice the array, the last object is always being deleted which is very strange as this should only be happening when the index I'm trying to delete doesn't exist (and therefore would equal -1)
Any ideas why this could be happening?
EDIT: I have also tried using ng-click="microsite.blocks.splice($index, 1)" directly in the element, as well as passing the $index into the function instead of the element. In all cases, the correct index is found, but the result is still the same, only the last entry is ever deleted.
Turns out this was an error with "track by $index" in Angular. After removing "track by $index" from my ng-repeat, splice() functioned normally.

Converting Handlebars expressing to lowercase and dashes

I am trying to reuse some of the data in my handlebars template on the front end.
To do this, I need to convert one of my expressions to lowercase, and use dashes instead of space. Is this easily done?
For example, in my JSON file I have the following:
var items = [{
id: '1',
title: "Item Number One",
},
{
id: '2',
title: "Item Number Two",
},
];
And on the Handbars template on the front-end I would like to do this:
<script type="text/x-handlebars" id="items">
<h1>
{{title}}
</h1>
<img src="{{unbound title}}.png" />
</script>
This will output the image page as <img src="Item Number One.png" /> which is no good. So is there an easy way of converting this to lowercase, and remove spaces?
Make a custom Handlebars Helper:
Handlebars.registerHelper("noSpaces", function(input) {
var output = input.toLowerCase();
return output.replace(" ", "");
});
And then call it as:
<img src="{{noSpaces title}}.png" />
You can map your items array and apply the template to that modified array like so:
var items = [
{
id: '1',
title: "Item Number One",
},
{
id: '2',
title: "Item Number Two",
},
];
items = items.map(function(el) {
el.title = el.title.toLowerCase().replace(/\s+/g, '-');
return el;
});
// items = [{id:"1",title:"item-number-one"},{id:"2",title:"item-number-two"}]
If you need to retain the original array just assign the mapped array to a different variable.

Specify id label for data loaded from array

Is it possible to load fully custom set of data into select2? I mean I can customize the option text property, can I also do it for id?
The code below works perfect
var dummy = [
{ id: 1, Name: "opt1" },
{ id: 2, Name: "opt2" }
];
$("#myselect").select2({
data: { results: dummy, text: "Name" },
formatSelection: function (item) { return item.Name; },
formatResult: function (item) { return item.Name }
});
However, my data incoming has the id property in caps. It surely would be possible for me to rename these objects' properties iterating through the received data set, yet the amount of data is pretty large and I certainly do not want to slow this simple load down. I'd also love to have these object properties stay.
Long story short, my data is like
var dummy = [
{ ID: 1, Name: "opt1" },
{ ID: 2, Name: "opt2" }
];
Is it possible to define an alternate id key?
yes, there is an option called id
Function used to get the id from the choice object or a string
representing the key under which the id is stored.
$("#myselect").select2({
id: 'ID',
data: { results: dummy, text: "Name" },
formatSelection: function (item) { return item.Name; },
formatResult: function (item) { return item.Name }
});

Categories