How can I parse this home-made string-based data format? - javascript

I need to iterate through a dataset of IDs and labels. I got some part of the code right, but I need some assistance.
// 1. String
var string = '1:answer1,2:answer2,3:answer3,4:answer4,5:answer5,'
// 2. Split to array
var string = string.split(",");
// 3. EACH
$.each(string, function(key, val) {
var answer = answer.split(":");
$.each(answer, function(key1, val1) {
// output textfield with id of key1 and value of val1
});
});
I can go through the first set of data, that is comma separated, but not the next (:). How do I do that?

$.each(string, function(key, val) {
var answer = val.split(":");
key1 = answer[0];
val1 = answer[1];
alert(key1+"--"+val1);
});

it should be var answer= val.split(":"); instead of var answer = answer.split(":");

You can use String.replace as an iterator:
var string = '1:answer1,2:answer2,3:answer3,4:answer4,5:answer5,'
var html = []
string.replace(/([^:]+):([^,]+)(,|$)/g, function(_, key, val) {
html.push("<input name='" + key + "' value='" + val + "'>")
});
alert(html.join("\n"))

Nothing against your home-made string of course, but have you considered using JSON for encapsulating data in a string. While JSON is universally usable it is probably the perfect match for JavaScript.
So if you would encode your data as follows it would really be a piece of cake to parse:
var data = [
{
"id": 1,
"answer": "answer1"
},
{
"id": 2,
"name": "answer2.. etc."
}
];
So now you can access your data very easily using array and property notation:
alert (data[0].answer);
Update: So in if you are lucky and your Rails app is on version 3.1 then adding support for JSON is really a piece of cake:
For basic JSON support the only thing you need to do is this:
# GET /answers/1
# GET /answers/1.json
def show
#answer = Answer.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json do
render json: #answer
end
end
end

Related

Json key has '#' Special character

Currently I need the URL for an image and I am getting it through the JSON file. I am not sure to acquire the key that has the URL due to the key having a # at the start. Here is the JSON:
{
"#text":"https://lastfm-img2.akamaized.net/i/u/34s/3ed37777196a6f2c29c02a1a58a93e4d.png",
"size":"small"
},
{
"#text":"https://lastfm-img2.akamaized.net/i/u/64s/3ed37777196a6f2c29c02a1a58a93e4d.png",
"size":"medium"
}
Same as with every other time you encounter some JSON string!
The # is an invalid character in a property name, work around is the bracket notation: «object»[property] --> «array»[index]['#text'].
We can use forEach to extract the results.
var string = '[{"#text":"https://lastfm-img2.akamaized.net/i/u/34s/3ed37777196a6f2c29c02a1a58a93e4d.png","size":"small"},{"#text":"https://lastfm-img2.akamaized.net/i/u/64s/3ed37777196a6f2c29c02a1a58a93e4d.png","size":"medium"}]';
var parsed = JSON.parse(string);
//parsed is an array, we can loop over it
parsed.forEach(function(obj) {
console.log(obj['#text']);
});
Even prettier would be if you can select from the array based on size:
var string = '[{"#text":"https://lastfm-img2.akamaized.net/i/u/34s/3ed37777196a6f2c29c02a1a58a93e4d.png","size":"small"},{"#text":"https://lastfm-img2.akamaized.net/i/u/64s/3ed37777196a6f2c29c02a1a58a93e4d.png","size":"medium"}]';
function getImageUrlBySize(size, json) {
var parsed = JSON.parse(json);
return parsed.find(function(element) { //modern browsers only (no IE)
return element['size'] == size;
})['#text']; //add text here since find returns the full item
}
console.log(getImageUrlBySize('small', string));

How to pass array with slashes or special characters?

I'm using the jquery get() function to send data. The data was array with information that can have special characters like / , ? and " . When this happens i can't access to url because the characters spoil the link.
How can i solve that? I did this:
function exemple()
{
$('.add').click(function(e)
{
var kitFamilia = $('#select-family').val();
var kitReference = $('#referenceinput').val();
var kitDescription = $('#descriptioninput').val();
var kitModel = $('#model-input').val();
var supplier = $('#select-supplier').val();
var details = [];
//alert(data);
details.push({stamp: stamp,family: kitFamilia, reference: kitReference, description: kitDescription, model: kitModel, supplier: supplier});
details = JSON.stringify(details, null, 2);
//alert(details);
$.get("/management-kit/create-kit/"+details, function(data)
{
location.reload();
});
e.preventDefault();
});
}
You should encode the data with encodeURIComponent
$.get("/management-kit/create-kit/"+encodeURIComponent(details), ..
Keep in mind that you are sending the JSON encoded as part of the path and not as a parameter. (and you might also want to remove the 2 space formating of the JSON as it will make the url quite longer)

Razor inside javascript key value declaration?

Given the need to extract data from a viewdata into a javascript key/value object:
var stuff = {
something : [#someVar.Prop2, #someVar.Prop3, etc]
};
I want to make the key have the "name" of someVar.Prop1 so that:
var stuff = {
#someVar.Prop1 : [#someVar.Prop2, #someVar.Prop3, etc]
};
Yet when I use the form in the second code block above, I get a Expected identifier, string or number error at the colon:
#someVar.Prop1 : [#someVar.Prop2, etc]
---------------X (x marks the spot)
How do I need to format the razor code so that it knows what I'm trying to say?
You should definitely not be trying to build your JSON piece by piece in your Razor view. That can go wrong very easily.
To expand on #DLeh's answer, what you can do is build a dictionary of the values you want, serialize that into JSON right in your Razor view, and assign that to your variable as shown here:
#{
// Assume that someVar is provided from somewhere else;
// this is just for demonstration
var someVar = new { Prop1 = "My Prop", Prop2 = "Prop Value", Prop3 = 7 };
}
#{
var obj = new Dictionary<string, object>
{
{someVar.Prop1, new object[] { someVar.Prop2, someVar.Prop3 } }
};
}
<script>
var stuff = #Html.Raw(Json.Encode(obj));
</script>
Rendered output:
<script>
var stuff = {"My Prop":["Prop Value",7]};
</script>
You can surround razor expressions in quotes ' or " to have them output into a javascript block. If you need the type to be preserved properly, you can use methods like parseInt() or parseFloat() to do so.
Example:
var stuff = {
value1 : '#val1',
value2 : [ parseInt('#val2'), parseInt('#val3') ]
};
If you need to left side of the assignment to be variable, you will probably need to build a json string and then parse that into the object. Something like this, my quotes might be off.
var stuffJson = '{"#value1" : "#val1", "#value2" : "[ #val2, #val3 ]" }';
var stuff = JSON.parse(stuffJson);
If you're doing this a lot, you might want to consider using the Json() method in your controller to help you build these more easily. You could build a dictionary of key / value and have that output json:
public virtual ActionResult GetStuff()
{
string value1 = "key1",
value2 = "key2",
val1 = "str1",
val2 = "str2",
val3 = "str3";
var dict = new Dictionary<string, object>
{
{ value1, val1},
{ value2, new List<string> { val2, val3} },
};
return Json(dict, JsonRequestBehavior.AllowGet);
}
Output:
{"key1":"str1","key2":["str2","str3"]}
The answer is to ignore Visual Studio's complaint of the problem as the code runs and throws no error:
#country.CountryCode: ['#someVar.Prop1', '#someVar.Prop2', etc],

How to push new key/value pair into external json file? [duplicate]

I have a JSON format object I read from a JSON file that I have in a variable called teamJSON, that looks like this:
{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}
I want to add a new item to the array, such as
{"teamId":"4","status":"pending"}
to end up with
{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}
before writing back to the file. What is a good way to add to the new element? I got close but all the double quotes were escaped. I have looked for a good answer on SO but none quite cover this case. Any help is appreciated.
JSON is just a notation; to make the change you want parse it so you can apply the changes to a native JavaScript Object, then stringify back to JSON
var jsonStr = '{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
var obj = JSON.parse(jsonStr);
obj['theTeam'].push({"teamId":"4","status":"pending"});
jsonStr = JSON.stringify(obj);
// "{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}"
var Str_txt = '{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
If you want to add at last position then use this:
var parse_obj = JSON.parse(Str_txt);
parse_obj['theTeam'].push({"teamId":"4","status":"pending"});
Str_txt = JSON.stringify(parse_obj);
Output //"{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}"
If you want to add at first position then use the following code:
var parse_obj = JSON.parse(Str_txt);
parse_obj['theTeam'].unshift({"teamId":"4","status":"pending"});
Str_txt = JSON.stringify(parse_obj);
Output //"{"theTeam":[{"teamId":"4","status":"pending"},{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}"
Anyone who wants to add at a certain position of an array try this:
parse_obj['theTeam'].splice(2, 0, {"teamId":"4","status":"pending"});
Output //"{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"4","status":"pending"},{"teamId":"3","status":"member"}]}"
Above code block adds an element after the second element.
First we need to parse the JSON object and then we can add an item.
var str = '{"theTeam":[{"teamId":"1","status":"pending"},
{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
var obj = JSON.parse(str);
obj['theTeam'].push({"teamId":"4","status":"pending"});
str = JSON.stringify(obj);
Finally we JSON.stringify the obj back to JSON
In my case, my JSON object didn't have any existing Array in it, so I had to create array element first and then had to push the element.
elementToPush = [1, 2, 3]
if (!obj.arr) this.$set(obj, "arr", [])
obj.arr.push(elementToPush)
(This answer may not be relevant to this particular question, but may help
someone else)
Use spread operator
array1 = [
{
"column": "Level",
"valueOperator": "=",
"value": "Organization"
}
];
array2 = [
{
"column": "Level",
"valueOperator": "=",
"value": "Division"
}
];
array3 = [
{
"column": "Level",
"operator": "=",
"value": "Country"
}
];
console.log(array1.push(...array2,...array3));
For example here is a element like button for adding item to basket and appropriate attributes for saving in localStorage.
'<i class="fa fa-shopping-cart"></i>Add to cart'
var productArray=[];
$(document).on('click','[cartBtn]',function(e){
e.preventDefault();
$(this).html('<i class="fa fa-check"></i>Added to cart');
console.log('Item added ');
var productJSON={"id":$(this).attr('pr_id'), "nameEn":$(this).attr('pr_name_en'), "price":$(this).attr('pr_price'), "image":$(this).attr('pr_image')};
if(localStorage.getObj('product')!==null){
productArray=localStorage.getObj('product');
productArray.push(productJSON);
localStorage.setObj('product', productArray);
}
else{
productArray.push(productJSON);
localStorage.setObj('product', productArray);
}
});
Storage.prototype.setObj = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObj = function(key) {
var value = this.getItem(key);
return value && JSON.parse(value);
}
After adding JSON object to Array result is (in LocalStorage):
[{"id":"99","nameEn":"Product Name1","price":"767","image":"1462012597217.jpeg"},{"id":"93","nameEn":"Product Name2","price":"76","image":"1461449637106.jpeg"},{"id":"94","nameEn":"Product Name3","price":"87","image":"1461449679506.jpeg"}]
after this action you can easily send data to server as List in Java
Full code example is here
How do I store a simple cart using localStorage?

Pass Array from MVC to javascript?

I can pass a variable from MVC ASP.NET by using this :
var lastCategoryId = '<%=Model.CS.LastSelectedCategory %>';
This work fine with string or integer but how do I do with an array of strings? I have tried to pass the array the same way but the variable is set to System.String[] ?
You could let .NET handle all the heavy lifting for you with this simple line of code.
This assumes you're using MVC Razor syntax.
var yourJavaScriptArray = #Html.Raw(Json.Encode(Model.YourDotNetArray));
For newer versions of MVC, use:
var yourJavaScriptArray = #Html.Raw(Json.Serialize(Model.YourDotNetArray));
You could JSON serialize it. This way could could pass even more complex values and not worry about escaping simple quotes, double quotes, etc :
var categoriesList = <%= new JavaScriptSerializer().Serialize(new[] { "value1", "value2" }) %>;
Writing an HTML helper to do this would be even better:
public static class HtmlExtensions
{
public static string JsonSerialize(this HtmlHelper htmlHelper, object value)
{
return new JavaScriptSerializer().Serialize(value);
}
}
and then in your view:
<script type="text/javascript">
var categoriesList = <%= Html.JsonSerialize(new[] { "value1", "value2" }) %>;
</script>
This should do
var someArray=[<%foreach (var s in myStringArray){%>'<%=s%>',<%}%>];
something like this:
<script type="text/javascript">
var myArr = [<%=string.Join(",", strArr.Select(o => "\"" + o + "\"")) %>];
</script>
One liner:
var data = [#Html.Raw(String.Join(",", Model.MyArray.Select(i => "'" + i + "'")))];
So easy, so simple
<script type="text/javascript">
var array = #Html.Raw(
Json.Encode(
(Model).Select(m=> new
{
id= m.ID,
name=m.Name
})
)
);
</script>
Output is:
[{"id":1,"name":"Name of 1"}, {"id":2,"name":"Name of 2"}, ...];
Using Json.NET
var yourlist = JSON.parse('#Html.Raw(JsonConvert.SerializeObject(Model.YourList))');
You need to format the array into a JavaScript array syntax.
var someArray = [<%= Model.SomeArray.Select(x => "'" + x +"'")
.Aggregate((x,y) => x + ", " + y); %>];
This will surround each entry by single quotes and then join them together with commas between square brackets.
Updated: removed extra parenthesis.
Just wanted to provide an answer using Razor syntax:
We have a Dictionary<int, int> that we are rendering for a jQuery Sparkline, in the form of "an array of arrays".
var usageData = [ #string.Join(",", Model.UsageData.Select(d => string.Format("[{0},{1}]", d.Key, d.Value)).ToArray()) ];
Which is used like so:
$('#sparkline').UsageSparkline(usageData, { tooltipFormatter: cachedTooltips });
This is what we get when viewing the source:
var usageData = [ [-13,0],[-12,1],[-11,0],[-10,0],[-9,1],[-8,1],[-7,0],[-6,2],[-5,2],[-4,0],[-3,0],[-2,9],[-1,3],[0,4] ];
$('#sparkline').UsageSparkline(usageData, { tooltipFormatter: cachedTooltips });

Categories

Resources