Javascript JSON object acess error - javascript

I've recently been working on a phonegap application using JSONP to create a dynamic feel. I have however recently hit a bit of a brick wall...
The following function is used to parse some delivery data (irrelevant) into jquery mobile:
function parseProdData(results) {
var html = '';
for (day in results.deliveries) {
var today = results.deliveries[day].delivery;
var today_date_arr = today.date.split('-');
var today_date = today_date_arr[2]+'/'+today_date_arr[1]+'/'+today_date_arr[0];
html += '<li><a href="#">';
html += today.delivery_day+', '+today_date;
html += '</a></li>';
console.log(html);
}
$('#JSON-list').append(html);
$('#JSON-list').trigger('create');
$('#JSON-list').listview('refresh');
}
Now all this looks like its working fine as when I check the console log I get:
<li>Thursday, 27/02/2014</li><li>Friday, 28/02/2014</li><li>Monday, 03/03/2014</li><li>Tuesday, 04/03/2014</li><li>Wednesday, 05/03/2014</li><li>Thursday, 06/03/2014</li><li>Friday, 07/03/2014</li>
Thus showing that it is accessing both the date and time attributes correctly. However, straight after this I get an uncaught type error:
Uncaught TypeError: Cannot read property 'date' of undefined
From my understanding of JS this should only happen when the relevant attribute is unset. As we can see from the html output in console, this is not the case as it is being accessed correctly.
Finally, I get exactly the same error (with delivery_day as the 'undefined' attribute) if I restrict the code to just the delivery day.
For those who would like it, below is a sample of the JSON code used:
{
"deliveries":[
{
"delivery":{
"delivery_day":"Thursday",
"date":"2014-02-27"
}
},
{
"delivery":{
"delivery_day":"Friday",
"date":"2014-02-28"
}
}
]
}
Does anyone have any idea why this error is popping up?
*EDIT*
Just to say, I'm fairly confident that the error is in the top part rather than the JQuery mobile elements as if I comment out the block $('#JSON-list').append(html); with $('#JSON-list').append(<li>Thursday, 27/02/2014</li><li>Friday, 28/02/2014</li>); then it works fine, but thats obviously not a solution.
*EDIT 2*
The issue was just that there was an empty element at the end of the 'deliveries' block, this was causing the uncaught error. I didn't notice it because the element was empty. Credit to #eithedog for pointing me in the right direction

I saved json data in result.json file then used this
$.getJSON('result.json', function(result, status){
var today = result.deliveries;
var html = "";
$.each(today, function(key, value){
$.each(value, function(key, value){
var today_date_arr = value.date.split('-');
var today_date = today_date_arr[2]+'/'+today_date_arr[1]+'/'+today_date_arr[0];
html += '<li>'+value.delivery_day+', '+today_date+'</li>';
})
})
$('#JSON-list').append(html);
$('#JSON-list').trigger('create');
$('#JSON-list').listview('refresh');
})
.success(function(result) {})
.fail(function(jqXHR, textStatus, errorThrown) {
})
.complete(function() { });

The issue was just that there was an empty element at the end of the 'deliveries' block, this was causing the uncaught error. I didn't notice it because the element was empty.
Credit to #eithedog for pointing me in the right direction.

Related

I need to call a calculate function from my backend JS file to my frontend HTML file where it is a button

My mentor told me I am supposed to do a $.post on my html file in order to get the answer my JS function will make for me. I cannot seem to get it right.
This is what my button looks like now:
<button style="margin-top:50px" type="button" id="calculate" onclick="addTip()",>Calculate!</button>
When I run it I get an error that says
currentTip.html:70 Uncaught ReferenceError: addTip is not defined at HTMLButtonElement.onclick
and also Uncaught ReferenceError: addTip is not defined
My function is running properly but this is what it looks like in my js file
function calculateTip(billamt, serviceQualEl) {
var roundedResult = (parseFloat(billamt) * parseFloat(serviceQualEl)).toFixed(2);
return roundedResult;
}
function calculatebillamtEl1(billamtEl1, tipAmount) {
return parseFloat(billamtEl1) + parseFloat(tipAmount);
}
function addTip() {
var serviceQualEl = document.querySelector("#serviceQual").value;
var billamtEl1 = document.querySelector("#billamt").value;
//sends tip amount with total to new page
function redirect(name, rating, tipAmount) {
$.post("/api/serviceQual", { name, rating, tipAmount }).then(function ()
{
window.location.replace("/previoustips")
});
}
I apologize I am not sure what to include in order to get proper help. Thank you.

AJAX success not render properly since second request

I use ajax to render output to below HTML element.
<p class="result-box" id="result-box">The result is : <br><strong id="result"></strong></p>
Everything works fine when rendering result for the 1st input request.
When I update my input, the console changes and prints desired data but the webpage including the text does not change.
I get Cannot read property 'setAttribute' of null at canvas_and_ploton the 2nd+ time refresh below, If I remove setAttribute, I get Cannot read property 'getAttribute' of null at canvas_and_plot.
$(document).on('submit','#cat_select',function(e){
e.preventDefault();
$.ajax({
type:'POST',
url:'/cat_select',
data:{
l2:$('#l2').val(),
l3:$('#l3').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
},
success: function server_response(response) {
const r = JSON.parse(response);
console.log(r); //updated
var cat_result = r.cat_result;
console.log(cat_result[0]) //updated
var text=$('<i></i>');
$.each(cat_result, function(idx, value) {
text.append('<id="result'+idx+'">' + cat_result[idx][0]+ '<br>'); //even the text output are not updated
text.append('<canvas id="canv_'+idx+'" width="200" height="200"></canvas><br>');
});
$('#result').replaceWith(text);
$.each(cat_result, function(idx, value) {
canvas_and_plot(idx,cat_result[idx][9],cat_result[idx][10],cat_result[idx][11])});
}
function canvas_and_plot(idx,a,b,c) {
var canv = document.getElementById('canv_'+idx);
canv.setAttribute('id', 'canv_'+idx);
var C = document.getElementById(canv.getAttribute('id'));
//plot...
}
I tried adding cache: false and adding random number to the url but neither of them works.
Why only error after the first request? How can I fix this? Thanks
The reason for it not changing is that you are replacing your block #result with received data.
$('#result').replaceWith(text);
After which you'll a dom tree that looks something like this:
<p class="result-box" id="result-box">
The result is : <br>
<i>
<id="result123">...<br>
<canvas id="canv123" width="200" height="200"></canvas><br>
<id="result321">...<br>
<canvas id="canv321" width="200" height="200"></canvas><br>
</i>
</p>
So the second time you click there is no element with #result id.
I suggest (as a rough and quick solution):
On every request remove all children of your #result element and fill it again with new data. So add this line before making the request - $('#result').empty(); and replace $('#result').replaceWith(text); with $('#result').append(text);
The main idea is to keep the place you put and add your server data. Hope this helps!

Meteor froala:editor-reactive save on change of data

I have Meteor project which uses the froala:editor-reactive package in order to set the user's about me field.
Here is my template js code:
Template.profile.helpers({
getAbout: function() {
return Meteor.user().profile.about;
},
doSave: function (e, editor) {
// Get edited HTML from Froala-Editor
var newHTML = editor.getHTML();
// Do something to update the edited value provided by the Froala-Editor plugin, if it has changed:
if (!_.isEqual(newHTML, Meteor.user().profile.about)) {
Meteor.call("updateTestimony", Meteor.userId(), newHTML);
}
return false; // Stop Froala Editor from POSTing to the Save URL
}
}
Here is my template html code:
<template name="profile">
<div>
{{> froalaReactive _onbeforeSave=doSave _value=getAbout}}
</div>
</template>
It's supposed to save as the value changes (I hope).
But I have an error with the line var newHTML = editor.getHTML(); and I've also tried var newHTML = editor.html.get(true);. Both of these result in an error where it cannot read the property of html or getHTML. I'm hoping this is just a syntax error and I need something else but what's wrong here?
Per the plugin docs, try:
var newHTML = editor.html.get(true /* keep_markers */);
If that doesn't work, you may possibly be using a different version. In which case, give the following syntaxes a shot:
var newHTML = $('.your_selector').editable('getHTML', true, true);
var newHTML = $('.your_selector').froalaEditor('html.get', true);
More from the official docs here and see this question.

Get JSON data from external URL and insert in a div as plain text

I have written a function to display some paragraph tags from an external webpage. For some reason the results are displayed in firebug console but not showing on the web page as I wanted (blank page).
function requestCrossDomain(callback){
var querylink = "select * from html where url='http://somedomain.com'" +
" and xpath='/html/body/div/div/div[2]/div/div/div/dl'";
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(querylink) + '&format=json&callback?';
$.getJSON(yql, function(data){
if (typeof callback === 'function'){
callback(data);
}
});
}
My firebug console shows the below value.
{"query":{"count":1,"created":"2013-12-23T06:31:46Z","lang":"en-US","results":{"dd":{"p":"Hills: High"}}}}
How can I modify the code to display the value of the P tag, which is "Hills: High"
I'm calling the function from HTML code and trying to display the value inside "#targetWrapper"
requestCrossDomain(function(results){
$('#targetWrapper').html(results);
});
Edited to reflect a functional fiddle
$(document).ready(function(){
requestCrossDomain();
});
function requestCrossDomain(){
var querylink = "select * from html where url='http://www.bom.gov.au/wa/forecasts" +
"/armadale.shtml' and xpath='/html/body/div/div/div[2]/div/div" +
"/div/dl'";
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(querylink) + '&format=json&callback?';
$.getJSON(yql, function(data){
$('#targetWrapper').html(data.query.results.dl.dd[0].p);
$("#targetWrapper").append("<br/><strong>" + JSON.stringify(data) + "</strong>");
});
}
Your data format was very much off the mark AND you cannot have two functions with the same name.
The object you get back from $.getJSON is a simple Javascript Object. You can access it just as you would any other object:
In this case, you'd use:
requestCrossDomain(function(results) {
$("#targetWrapper").html(results.query.results.dd.p);
}
I would highly recommend that you read the MDN documentation I linked above. Having MDN bookmarked is also a good idea; it's a great resource to have easy access to.

jQuery Remove part of the HTML and append new HTML

We have approval with our client, just a heads up to cover me in any way.
We are needing to modify some of the code in a clients site if a cookie is seen on their computer, the client's site is in ASPX format. I have the first part of the code created, but where I am getting stuck is this:
I need to remove the last 2000 characters (or so) of the body of the page, then append the new HTML to it.
I tried:
$('body').html().substring(0, 10050)
but that doesn't work, I also tried copying that HTML (which did work) and put it back with the new code, but it created a loop of the script running.
Any suggestions on what I should do? It has to be javascript/jQuery sadly.
//////// EDIT ////////////
My script is brought in by Google Tag Manager, and added to the page at the bottom, then my script runs, this is what was causing the loop in the script. Basically, here is the setup:
My Script on my server is loaded into the client site using Google Tag Manager, added to the bottom of the page. From there it is able to execute, but when doing this, it creates a loop of adding the Google Tag Manager script, causing my code to re-add, causing it to re-execute again.
The client is not willing to do anything, he has pretty much told us to just figure it out, and to not involve his web guy.
This is the code straight from their site I am trying to edit.
<script language="JavaScript">
jQuery(function($){
$('#txtPhone').mask('(999) 999-9999? x99999');
$('#submit').click(function(){CheckForm();});
});
function CheckForm(theForm){
if (!validRequired($('#txtfirst_name'),'First Name')){ return false; }
if (!validRequired($('#txtlast_name'),'Last Name')){ return false; }
if (!validRequired($('#txtEmail'),'E-Mail Address')){ return false; }
if (!validEmail($('#txtEmail'),'E-Mail Address',true)){ return false; }
if (!validPhone($('#txtPhone'),'Phone Number')){ return false; }
var dataList='fa=create_lead';
dataList += '&name=' + $('#txtfirst_name').val();
dataList += '&lastname=' +$('#txtlast_name').val();
dataList += '&email=' + $('#txtEmail').val();
dataList += '&phone=' + $('#txtPhone').val();
dataList += '&vid=' + dealerOnPoiVisitId;
dataList += '&cid=' + dealerOnPoiClientId;
dataList += '&leadType=9';
dataList += '&leadSrc=32'; ////////////////////// THIS IS WHAT I AM ATTEMPTING TO CHANGE /////////////////////////
dataList += '&contactname=' + $('#contactname').val();
dataList += '&comment=' + encodeURIComponent($('#txtComments').val());
dataList += '&dvc=' +encodeURIComponent(DealerOn_Base64.encode($('#txtfirst_name').val() + $('#txtEmail').val()));
var lid=1;
$('#submit').prop('disabled', true);
$.ajax({
url:'/lead.aspx',
data: dataList,
dataType: 'json',
success: function(data){
$('#submit').prop('disabled', false);
lid=data.leadid;
if (lid > 1){
$('#submit').prop('disabled', false);
var jqxhr = $.post('/lead.aspx?fa=complete_lead&leadid=' + lid , function() {
window.location.href='/thankyou.aspx?name=' + $('#txtfirst_name').val() + '&lid=' + data.leadid;
});
}
},
error: function(request,error) {
$('#submit').prop('disabled', false);
}
});
}
</script>
This is the page on the site: www.moremazda.com/contactus.aspx
You have to add the HTML back:
var html = $('body').html().substring(0, 10050);
$('body').html(html);
Note that doing this, and just randomly removing chunks of HTML is not good practice, and could lead to a number of problems.
Technically you should be able to do this:
var bodyHTML = $('body');
bodyHTML.html(bodyHTML.html().substring(2000));
But as I pointed out in my comment above, that is a REALLY BAD idea.
If you have access to the HTML to the page, wrap the code you want to replace in a identifiable tag and remove that. I.e.:
<div id="tobeRemoved">Lorem Ipsum</div>
<script>
$('#toBeRemoved').empty();
</script>
If you can't edit the HTML, but you know that it is always the last script tag, you could do something like this:
var scripts = $('script');
scripts.get(-1).remove;

Categories