JSON.stringify not working in IE10 - javascript

I am trying to parse some form data to produce JSON data to send in an ajax request. The following HTML is an oversimplified version of my code. I'm using APS.Net MVC4 and my rendered view produces the following HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<div class="test-class" data-my-attribute="1"></div>
<div class="test-class" data-my-attribute="2"></div>
<div class="test-class" data-my-attribute="3"></div>
<script src="/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
jsonObj = [];
$(".test-class").each(function () {
var myAttribute = $(this).data('my-attribute');
item = {}
item["MyAttribute"] = myAttribute;
jsonObj.push(item);
});
var data = { SomeOtherData: 1234, MyAttribs: jsonObj };
console.log(JSON.stringify(data));
});
</script>
</body>
</html>
In Chrome the output in the console is output as expected ...
{
"SomeOtherData": 1234,
"MyAttribs": [{
"MyAttribute": 1
}, {
"MyAttribute": 2
}, {
"MyAttribute": 3
}]
}
... but in IE the objects come out as null ...
{
"SomeOtherData": 1234,
"MyAttribs": [null, null, null]
}
I've had a look around and found some other questions that recommend checking that the page has <!DOCTYPE html> in it (which it does) and that doesn't seem to have any effect. I've also read that this should work in from IE8 onward so not sure what's happening.
Does anyone know why the objects are appearing as nulls in IE?
What is the best cross-browser solution to this?
Thanks,
Gavin

The only weird thing I see is that:
item = {}
Should be:
var item = {}; // 'var' and semicolon
Sometimes IE is quite strict..

on my case use as #palvo sayed console.dir(obj)
other alternative is JSON2 from douglascrockford

Related

when i try to access array element by index it gives me undefined

i created an array and insert elements by array.push(). when i console.log(array) it gives me following out put output of console.log(array)
when i console.log(array[0]) it gives me undefined. why is happing and a blue i tag appear in picture which says "this value was evaluated on first expanding it may have changed since then in array javascript" what does means. please help me to understand the problem
here the full code
index.html =>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>zip reader</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.3/jstree.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<body>
<h3>Choose the local(s) zip file(s)</h3>
<input type="file" id="file" name="file" multiple /><br />
<div id="result_block" class="hidden">
<h3>Content :</h3>
<div id="result">
</div>
</div>
</body>
<script src="jszip.min.js"></script>
<script src="jszip-utils.min.js"></script>
<script src="app1.js"></script>
<script src="FileSaver.min.js"></script>
</html>
app1.js =>
var array = []
var contents = []
var $result = $("#result");
$("#file").on("change", function(evt) {
// remove content
$result.html("");
// be sure to show the results
$("#result_block").removeClass("hidden").addClass("show");
// Closure to capture the file information.
function handleFile(f) {
var $title = $("<h4>", {
text : f.name
});
var $fileContent = $("<ul>");
$result.append($title);
$result.append($fileContent);
var dateBefore = new Date();
JSZip.loadAsync(f) // 1) read the Blob
.then(function(zip) {
var dateAfter = new Date();
$title.append($("<span>", {
"class": "small",
text:" (loaded in " + (dateAfter - dateBefore) + "ms)"
}));
zip.forEach( function (relativePath, zipEntry) {
var y = zipEntry.name
array.push(y);
$fileContent.append($("<li>", {
text : zipEntry.name
}));
});
}, function (e) {
$result.append($("<div>", {
"class" : "alert alert-danger",
text : "Error reading " + f.name + ": " + e.message
}));
});
}
var files = evt.target.files;
for (var i = 0; i < files.length; i++) {
handleFile(files[i]);
}
console.log(array[0])
});
When you console.log an object (including arrays), it isn't being serialized, and only a reference is passed to a console. When you expand it, this reference is used to check the state of this object.
Most probably what's happening is the following sequence:
console.log(array) // passes array reference to a console
console.log(array[0]) // prints undefined immediately
array.push(...) // an actual array modification
you expand the object, and console checks the content of an array
PS.
It's reasonable to ask, what will happen, if the reference will become invalid due to any reason.
For browsers - it's simpler, since the console and JS program run under same parent process, browser is responsible for everything.
But if you'll ever try to debug Node process, which has the same API of passing the reference, you will face strange issues all over around, like this one: No debug adapter, can not send 'variables VSCODE

Polymer 1.x: How to format a number while typing it into paper-input?

TL;DR: I want my numbers to look like 1,500 (not 1500) when entering it in an <input (actually <paper-input or even <iron-input?) form field. Similar to this example except using Polymer only and not AngularJS.
I want to format a number in paper-input (using, say, Numeral.js) while it's being entered by the user. I don't really know where to begin or what to try. I want to access the numeric value in the JS, but I want the user to be able to see the nicely formatted (string) version while entering it.
Is this even possible? Or perhaps I might need a separate display field? But then that would defeat the purpose of the paper-elements from a UX standpoint? Any help?
Also, note per the second comment on this SO question:
Worth noting that Number.prototype.toLocaleString still does not work in Safari, in 2016. Instead of actually formatting the number, it just returns it, no error thrown. Having the biggest facepalm today as a result of that... #goodworkApple – aendrew
Here is the jsbin. ... http://jsbin.com/wosoxohixa/1/edit?html,output
http://jsbin.com/wosoxohixa/1/edit?html,output
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<paper-input value="{{num}}"></paper-input>
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
num: {
type: Number,
value: function() {
return numeral(1500).format('0,0');
},
},
},
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
Based on the answer from #akc42, I constructed the following working jsBin. ... http://jsbin.com/zunezojuzu/1/edit?html,console,output
http://jsbin.com/zunezojuzu/1/edit?html,console,output
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<paper-input value="{{num}}"></paper-input>
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
num: {
type: String,
observer: '_numChanged',
},
},
attached: function() {
this.numBeingChanged = false;
},
_numChanged: function(num) {
console.log('num', num);
if (!this.numBeingChanged) {
this.numBeingChanged = true; //prevent recursion
var x = num.replace(/\D/g,'')
x = parseInt(x);
console.log('x', x);
this.set('num', numeral(x).format('0,0'));
this.numBeingChanged = false;
}
}
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
I do something similar with a datepicker based around paper input. Put an observer on the num property, and it will get called as every new character arrives.
You also need to be careful with validation as you may end up trying to validate 1,0 if that is the way the user has typed it in. (assuming he may type with or without your formatiing

How to read object properly in JavaScript

I am new to programming and recently began learning Javascript, I have a problem that appeared in few exercises that I made. I searched the site for more information but have not found a solution for my problem. I apologize in advance for my bad english and if this is not the right place or the right way to ask this question because this is my first post in Stackoverflow.
Currently practicing HTML templates. Assuming that the code is correct, I'm not sure where I'm wrong. Loading code into the browser and Handlebars gives me an error: "Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed undefined". I tried to debug and saw that when I tried to take a value from date object it gives back undefined. In previous exercise had a similar problem in which I tried to read JSON object and did not manage to parse it and returned again undefined. Can you help me, I am stuck on this problem for some time.
var data = {
animals: [{
name: 'Lion',
url: 'https://susanmcmovies.files.wordpress.com/2014/12/the-lion-king-wallpaper-the-lion-king-2-simbas-pride-4685023-1024-768.jpg'
}, {
name: 'Turtle',
url: 'http://www.enkivillage.com/s/upload/images/a231e4349b9e3f28c740d802d4565eaf.jpg'
}, {
name: 'Dog'
}, {
name: 'Cat',
url: 'http://i.imgur.com/Ruuef.jpg'
}, {
name: 'Dog Again'
}]
}
window.onload = function() {
var htmlTemplate = document.getElementsByClassName('container-template').innerHTML;
var template = Handlebars.compile(htmlTemplate);
for (let x of data.animals) {
if (x.hasOwnProperty('url')) { //x.url
x.hasUrl = true;
} else {
x.hasUrl = false;
}
}
document.getElementsByClassName('container').innerHTML = template(data);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Animals & Batman</title>
</head>
<body>
<div class="container">
</div>
<script class="container-template" type="text/x-handlebars-template">
<h1>Animals</h1>
{{#each animals}}
{{#if hasUrl}}
<li>
See a {{name}}
</li>
{{else}}
<li>
No link for {{name}}, here is Batman!
</li>
{{/if}}
{{/each}}
</script>
<script src="../handlebars-v4.0.5.js" charset="utf-8"></script>
<script src="../jquery-3.1.0.js" charset="utf-8"></script>
<script src="./main.js" charset="utf-8"></script>
</body>
</html>
document.getElementsByClassName returns an array of elements, not a single one - since multiple elements on a page can have the same class.
What you probably want is to use the id instead of class:
<script id="container-template" type="text/x-handlebars-template">
var htmlTemplate = document.getElementById('container-template').innerHTML;

Using Javascript to return a single value to HTML from a JSON file

I've had a look around at 2 or three different ways to do this, however I'm still encountering problems.
With the below I can generate an alert, but nothing gets written to the div
JSON
{
"FixVersion": "Version - 1.2.3",
"BugCount": "27",
"TaskCount": "4",
"StoryCount": "5"
}
JAVASCRIPT ATTEMPT 1
<script type="text/javascript">
function read_project_title() {
$.getJSON("ProjectVersion.json", function(data) {
alert(data["FixVersion"]);
return(data["FixVersion"]);
});
}
</script>
JAVASCRIPT ATTEMPT 2
<script type="text/javascript">
function read_project_title() {
$.getJSON("ProjectVersion.json", function(data) {
var node = document.getElementById('pageTitle');
node.innerHTML(data["FixVersion"]);
});
}
</script>
HTML
<div id="pageTitle"><script>read_project_title();</script></div>
did you tried this way?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="pageTitle"></div>
<script>
function read_project_title() {
$.getJSON("ProjectVersion.json", function(data) {
var node = document.querySelector('#pageTitle');
if (node) {
node.innerHTML = data.FixVersion;
}
});
}
read_project_title();
</script>
</body>
</html>
Try this
<script type="text/javascript">
function read_project_title() {
$.getJSON("ProjectVersion.json", function(data) {
alert(data.FixVersion);
return(data.FixVersion);
});
}
</script>
In your second attempt, simply change the line node.innerHTML(data["FixVersion"]); to:
node.innerHTML = data["FixVersion"];
Hope it helps.
simple fix! just print out all returned data to make sure you're getting what you expect
DEMO
$(function() {
$.getJSON('objects.json',function(data) {
$('#pageTitle').html(data['FixVersion']);
// print data
document.body.innerHTML += JSON.stringify(data, null, 4);
});
});

jQuery template not showing data elements

I'm trying to get the jQuery template feature working but have finally come to a dead end. From all my investigation the code listing below should work and I expect to get:
file1.txt, 123456, 2012-01-01
file2.txt, 234567, 2012-01-02
file3.txt, 345678, 2012-01-03
but instead I get
, ,
, ,
, ,
Clearly the library is loading and the code is running but for some reason it will not pick up the data elements. The code behaves the same regardless of the browser. I've tried compiling the template and not, each with the same results.
I'm sure that I'm missing something simple, but I've been pulling my hair out for about 8 hours staring at examples (and I've not that much hair left!). Thanks in advance for any assistance.
<html lang="en">
<head>
<title>jQuery Template Test</title>
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<script src="inc/jquery.tmpl.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var exampleData = [
{ name: "file1.txt", size: "123456", date: "2012-01-01" },
{ name: "file2.txt", size: "234567", date: "2012-01-02" },
{ name: "file3.txt", size: "345678", date: "2012-01-03" }
];
var markup = "<li>${name}, ${size}, ${date}</li>";
$.template( "exampleTemplate", markup );
$.tmpl("exampleTemplate", exampleData).appendTo("#target");
});
</script>
</head>
<body>
<ul id="target"></ul>
</body>
</html>
I had the same problem with JSP: Use \$ to escape EL expression

Categories