Convert String to an Array in JS - javascript

In my project I have a use case like the below:
I have a response Array like below,
(4) [{…}, {…}, {…}, {…}]
0:{header: 0, name: "Name", field: "Id"}
1:{header: 3, name: "LastName", field: "Agreement__c"}
2:{header: 3, name: "LastName", field: "Amount__c"}
3:{header: 3, name: "LastName", field: "BIC__c"}
length:4
from the above I convert the above array to String by using,
JSON.stringify(responseArray) and store it in a string field.
After that I want to do some manipulation dynamically to that value of that field. So when I get the value back from the field it came as like below,
[{"header":0,"name":"Name","field":"Id"},
{"header":3,"name":"LastName","field":"Agreement__c"},
{"header":3,"name":"LastName","field":"Amount__c"},
{"header":3,"name":"LastName","field":"BIC__c"}]
Anyone please help me to convert the above string response to an Array in Javascript like as follows,
index 0 -> {"header":0,"name":"Name","field":"Id"}
index 1 -> {"header":3,"name":"LastName","field":"Agreement"}
I have tried with the split function but couldn't able to achieve the exact need.

Put square brackets at the beginning and end of your string and call JSON.parse:
$ node
> const text = `{"header":0,"name":"Name","field":"Id"},
{"header":3,"name":"LastName","field":"Agreement"},
{"header":3,"name":"LastName","field":"Amount"},
{"header":3,"name":"LastName","field":"BIC"}`
> JSON.parse(`[${text}]`)
[ { header: 0, name: 'Name', field: 'Id' },
{ header: 3, name: 'LastName', field: 'Agreement' },
{ header: 3, name: 'LastName', field: 'Amount' },
{ header: 3, name: 'LastName', field: 'BIC' } ]

you can use following code sample first append "[" at begging of your string and "]" at end of your string so your string will be well formatted as JSON array then it is so easy to parse it using JSON.parse built in function
a = '['+'{"header":0,"name":"Name","field":"Id"}, {"header":3,"name":"LastName","field":"Agreement"}, {"header":3,"name":"LastName","field":"Amount"}, {"header":3,"name":"LastName","field":"BIC"}'+"]"
var myarray = JSON.parse(a);

yes, JSON.parse is the real easy answer for this.

You just need some basic string manipulations, By the way, I changed your string into a valid syntax
var str="{\"header\":0,\"name\":\"Name\",\"field\":\"Id\"},{\"header\":3,\"name\":\"LastName\",\"field\":\"Agreement\"},{\"header\":3,\"name\":\"LastName\",\"field\":\"Amount\"},{\"header\":3,\"name\":\"LastName\",\"field\":\"BIC\"}";
str=str.replace(/},{/g,"}|{");
var arr = str.split("|");
var json = [];
for(i=0; i<arr.length; i++){
json.push(JSON.parse(arr[i]));
}
//console.log(json);
console.log(json[0]);
console.log(json[1]);

try this
var textstr = '[{"header":0,"name":"Name","field":"Id"},{"header":3,"name":"LastName","field":"Agreement"}, {"header":3,"name":"LastName","field":"Amount"}, {"header":3,"name":"LastName","field":"BIC"}]';
var textstr2 = JSON.parse(textstr);
console.log(textstr2)

Related

How can I loop through an array with razor and javascript together ASP.net

I am currently using ASP.NET MVC, I am using javascript to create a graph that represents data in my models.
The Javascript is expecting the data in this format:
series: [{
name: 'Bench',
data: [
10, 20, 30
]
}],
However, I am trying to use razor to loop through my array in the data field as so:
series: [{
name: 'Bench',
data: [
#for (int j = 0; j < numArry.Length; j++)
{
numArry[j] + ",";
}
]
}],
My issue is that the comma that separates my integers is not accepted by razor syntax. I need to comma to be repeated after every array integer otherwise the graph will only contain the last integer in the array.
series: [{
name: 'Bench',
data: [
#numArry[0]
,
#numArry[1]
,
#numArry[2]
,
#numArry[3]
]
}],
This is my current solution that does work however, I can enter every element of the array manually.
Try it following ways..
Create Model with same structure and serialize it to JSON
Move the for loop outside of the series and declare a variable before the series code as below to get comma separated value.
# {
var str = String.Join(",", numArry);
}
series: [{
name: 'Bench',
data: [ { # {str } ]
}],

Convert user input string to an object to be accessed by function

I have data in the format (input):
doSomething({
type: 'type',
Unit: 'unit',
attributes: [
{
attribute: 'attribute',
value: form.first_name
},
{
attribute: 'attribute2',
value: form.family_name
}
],
groups: [
{
smth: 'string1',
smth2: 'string2',
start: timeStart.substring(0, 9)
}
]
})
I managed to take out the doSomething part with the parenthesis as to load the function from the corresponding module with
expression.split('({',1)[0]
However using the loaded function with the rest, obtained with:
expression.split(temp+'(')[1].trim().replace(/\n+/g, '').slice(0, -1)
does not work because it should be an object and not a string. Hardcoding the data in does work as it is automatically read as an object.
My question is if there is any way of converting the string that I get from the user and convert it to an object. I have tried to convert it to a json object with JSON.parse but I get an unexpected character t at position 3. Also I have tried new Object(myString) but that did not work either.
What I would like is to have the body of the provided function as an object as if I would hard code it, so that the function can evaluate the different fields properly.
Is there any way to easily achieve that?
EDIT: the "output" would be:
{
type: 'type',
Unit: 'unit',
attributes: [
{
attribute: 'attribute',
value: form.first_name
},
{
attribute: 'attribute2',
value: form.family_name
}
],
groups: [
{
smth: 'string1',
smth2: 'string2',
start: timeStart.substring(0, 9)
}
]
}
as an object. This is the critical part because I have this already but as a string. However the function that uses this, is expecting an object. Like previously mentioned, hard coding this would work, as it is read as an object, but I am getting the input mentioned above as a string from the user.
Aside: I know eval is evil. The user could do by this certain injections. This is only one possibility to do this there are certain other ways.
I just added before "output =", cut from the input-string the "doSomething(" and the last ")". By this I have a normal command-line which I could execute by eval.
I highly not recommend to use eval this way; especially you don't
know what the user will do, so you don't know what could all happen
with your code and data.
let form = {first_name: 'Mickey', family_name: 'Mouse'};
let timeStart = (new Date()).toString();
let input = `doSomething({
type: 'type',
Unit: 'unit',
attributes: [
{
attribute: 'attribute',
value: form.first_name
},
{
attribute: 'attribute2',
value: form.family_name
}
],
groups: [
{
smth: 'string1',
smth2: 'string2',
start: timeStart.substring(0, 9)
}
]
})`;
let pos= "doSomething(".length;
input = 'output = ' + input.substr(pos, input.length-pos-1);
eval(input);
console.log(output);

How to convert stringified surveyjs JSON-like object into actual JSON

I'm working on a an application that uses the survey building library surveyjs. I'm building a tool where users can input a survey JSON from that website into a form that is then sent as a string via an ajax request that triggers an AWS Lambda function. The lambda function takes the ajax request and inserts their survey into a MongoDB instance using mongoose.
When the string comes into the lambda function, it looks like this:
"{ pages: [ { name: 'page1', elements: [ { type: 'radiogroup', name: 'question1', title: 'IS THIS A SURVEY?', choices: [ { value: 'item1', text: 'Yes' }, { value: 'item2', text: 'No' } ] } ] } ]}"
And when I try to parse that string, I get this error:
Error: JSON Parse error: Expected '}'
I think it might have something to do with the JSON keys not being strings. I've also read that my use of single quotes could potentially be the problem, but I've exhausted my knowledge base.
Overall, my question is: How can I convert that string into a JSON object?
Thanks!
JSON strings need their string properties and values to be double-quoted. Use a regular expression and replace:
const originalStr = "{ pages: [ { name: 'page1', elements: [ { type: 'radiogroup', name: 'question1', title: 'IS THIS A SURVEY?', choices: [ { value: 'item1', text: 'Yes' }, { value: 'item2', text: 'No' } ] } ] } ]}";
const finalStr = originalStr
.replace(/'/g, '"')
.replace(/(\w+):/g, '"$1":');
console.log(JSON.parse(finalStr).pages);
That said, it would be better to fix whatever's serving the results in the first place, if at all possible.
If your lambda function is written using javascript then you can make use of eval to parse malformed JSON, however the eval'd string is evaluated as actual javascript within the current context so to get the result you have to set a variable within the string. Example:
var malformedJsonString = "{unquotedName: 'single quoted value'}";
eval("var myParsedJsonObject = "+malformedJsonString+";");
// myParsedJsonObject now contains your parsed JSON object

AngularJS : How to concat two arrays?

I have following arrays with values (i am generating the values on go)
$scope.objectName = [{ Name: '' }];
$scope.propertiesElement = [{ Key: '', Value: '' }];
I want to concatenate these two objects to get the following result
[{Name:''},{ Key: '', Value: '' }]
Plunker link , somehow that's not working either
when I click on the add row button it will add another row for key and value text boxes only not for name, I can add n no of rows and when I click on Submit it should show the kev value pair as
[{Name:''},{ Key: '', Value: '' },{ Key: '', Value: '' },{ Key: '', Value: '' }.....so on]
Thanks
Not sure why you want to build an array of mismatched objects. That seems to me to be asking for trouble. I would suggest possibly doing the following:
$scope.objects = [{Name: '', Elements: []}];
Then you can easily manage multiple objects who have elements:
(I use underscore http://underscorejs.org/)
$scope.addElementToObject = function(objName, element){
_.where($scope.mergedArray, {Name: objName}).Elements.push(element);
};
Then you can add to the list of elements for that object without having to eval the object in the elements array on each use.
If you still want/need to merge arrays of mismatched objects, it would be the following:
$scope.objectName = [{ Name: '' }];
$scope.propertiesElement = [{ Key: '', Value: '' }];
$scope.mergedArray = $scope.objectName.contact($scope.propertiesElement);
$scope.addElement = function(element){
$scope.mergedArray.push(element);
};
Then, in your click event code:
$scope.addElement({ Key: 'someKey', Value: 'Some Value' });
I hope this helps.

is there a way in Slick.Grid to render all data to an array so it can be exported?

Is there a way in Slick.Grid to render all data to an array so it can be exported?
I am able to get the data from my Slick.Grid instance "mygrid.getData().getItems()" but it is just the raw data not the formated data.
Is there a function I can use to iterate though the collection and return the formated data?
As of now I am having to implement my formatters twice.
Example:
UnixToDate: (row, cell, value, columnDef, dataContext) ->
moment.unix(value).format("MMM Do YY")
items: [
{id: 1, activity_at: 915148798 },
{id: 2, activity_at: 999148800 }
]
columns: [
{field: 'id', id: 'id', name: 'Id'},
{field: 'activity_at', id: 'activity_at', name: 'Activity', formatter: UnixToDate}
]
#data = new Slick.Data.DataView()
#grid = new Slick.Grid( $('#table'), #data, columns )
#data.setItems(items)
I am wondering if there is a way to return the data with the formatted values.
I thought #grid.getData().getItems() would do it but it returns the raw data array.
The data returned should look like:
data: [
{id: 1, activity_at: "Dec 31st 98" },
{id: 2, activity_at: "Aug 29th 01" }
]
I would like the end user to be able to filter and arrange the grid and then export the results in csv format, I have all this working except the formatting part.
Ok I wrote a method to do the export (written in coffeescript and using underscore.js). I also had to expose the getFormatter method in slick.grid.js
getFormattedData: (grid) ->
columns = grid.getColumns()
rows = grid.getData().getItems()
_(rows).map (row) ->
h = {}
i = 0
_(columns).each (column) ->
f = grid.getFormatter(row, column)
h[column.id] = f(row, i, row[column.id], column, row)
i += 1
h
add line to slick.grid.js in the // Public API section
"getFormatter": getFormatter,
When you set autoHeight: true the complete grid is rendered and the html could be exported.
http://mleibman.github.com/SlickGrid/examples/example11-autoheight.html
Answer to updated question:
The formatter is only called when a row is rendered/visible, so an array with the formatted data never exists. At the source: https://github.com/mleibman/SlickGrid/blob/master/slick.grid.js#L1291

Categories

Resources