uncaught error data undefined on ajax call - javascript

I'm making an ajax call (JavaScript) which generates through the show info function the data I'm retrieving. My problem is as follows: On one of the arrays some data don't have it, there are not many but there is still some. So it's displaying the first items but it stops when it can't retrieve the said array and return a:
Uncaught TypeError: info["xxxx"] is undefined.
What I'd really like is to be able to make it so it still retrieve / display the datas and says something like 'this data.[denomination][0].title is undefined or anything else'.
I tried to use the optional chaining operator '?.' but I clearly have no idea on how it works.
Here's what makes me get crazy: (it's the data["denomination"] that ruins it all)
request.addEventListener('readystatechange', function(){
if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
const backCall=JSON.parse(request.responseText);
if(backCall.count != 0){
for(let data of backCall.datas){
showInfo(data.title, data["author"][0].name, data["denomination"][0].title, data["denomination"][0].id);
}
}else if(backCall.count === 0){
noResult();
}
}
});
(just a little edit to be precise. I searched before hand and even looked up to the advised subjects from Stack when I was writing this)

Check if both properties exist in the object and then call your showinfo function, it should not fail
for (let data of backCall.datas) {
if (data["author"] && data["denomination"]) {
showInfo(data.title, data["author"][0].name, data["denomination"][0].title, data["denomination"][0].id);
}
}

Related

Leaflet JS Visualization through static API response using JQuery

I'm getting a static response from an API (it returns the same data on every call) and based on that response I'm changing visualization properties of a GeoJSON object.
Currently my workflow is:
Read GeoJSON in frontend
Hit API to get its response
Loop through the api keys and match them with GeoJSON's key. Symbolize based on value when ID gets matched.
The issue with this approach is that on every event, I'm making a new request and getting the same data. Also, after getting the data, the loop takes lots of time to complete and then the visualization property gets applied.
I have tried storing API response in a variable in the frontend code as well but the time taken while looping through the ID's is still a lot. I can't think of any ways to store the visualization properties somewhere to make the symbology change of GeoJSON rapidly.
Some code example to implement this would be helpful. My current code is shared below:
$(".ambtn").on("click",function(){
$.ajax({
method:"get",
url:"/los_am",
beforeSend: function(){
$("#loader").css({
display: "inline-block",
visibility: "visible"
});
},
complete: function(){
$("#loader").css({
display: "none",
visibility: "hidden"
});
},
success:function(res){
// console.log(res)
rdNetworkLyr.eachLayer(function (layer) {
for (const key in res.XDSegID){
if(res.XDSegID.hasOwnProperty(key)){
if(layer.feature.properties.XDSegID === res.XDSegID[key] && res.los[key] === 'A'){
layer.setStyle({color:'#060'})
}
else if (layer.feature.properties.XDSegID === res.XDSegID[key] && res.los[key] === 'B'){
layer.setStyle({color:'#9f0'})
}
else if (layer.feature.properties.XDSegID === res.XDSegID[key] && res.los[key] === 'C'){
layer.setStyle({color:'#ff3'})
}
else if (layer.feature.properties.XDSegID === res.XDSegID[key] && res.los[key] === 'D'){
layer.setStyle({color:'#f90'})
}
else if (layer.feature.properties.XDSegID === res.XDSegID[key] && res.los[key] === 'E'){
layer.setStyle({color:'#f60'})
}
else if (layer.feature.properties.XDSegID === res.XDSegID[key] && res.los[key] === 'F'){
layer.setStyle({color:'#c00'})
}
}
}
});
}
});
});
My aim is to pass that stored symbology to "setStyle" function without having to loop every time the request is made.
the loop takes lots of time to complete
the time taken while looping through the ID's is still a lot
Unless you have millions of keys to loop through, the algo part in itself is rarely the bottleneck.
What may slow down things is the style change of individual layers in your GeoJSON Layer Group rdNetworkLyr: if that makes the browser recompute and repaint the entire Group at every individual change, for sure it will take a lot of work at every step, especially if your group is big!
You can try a simple workaround by removing your rdNetworkLyr Layer Group from the map first before applying all the individual style changes, then adding it back:
function (res) {
rdNetworkLyr.remove();
// Change all the styles
rdNetworkLyr.addTo(map);
}

How to create a conditional based on a response object, for which the Key values are dependent and avoiding object.key() is Undefined

I'm subscribing to a method in Angular using typescript, which is a simple post Call that returns an entire HTTP Response. I'm wanting to create a simple conditional that checks to see if a certain key exists in the HTTP response. The conditional will work with an object that contains the key, but for an object that doesn't contain the key it throws an undefined.
Is there a way to omit the error or exception thrown and to proceed to the else portion
The keys of the object body are added if the user includes a number, without that it doesn't exist with the PhoneNumber key value
what I've tried / flipped the if and else
!= undefined (vice versa)
== null (vice versa)
this.postMyName(userInfo).subscribe(
(result:Response) => {
if (result['body']['user'].hasOwnProperty(['PhoneNumber'])) {
console.log("User has included a phoneNumber");
} else {
console.log("User has Not included a phoneNumber");
}
},error ...)
You can also try this solution maybe it will work
this.postMyName(userInfo).subscribe(
(result:Response) => {
if ('PhoneNumber' in result['body']['user'])) {
console.log("User has included a phoneNumber");
} else {
console.log("User has Not included a phoneNumber");
}
},error ...)

Dynamoose/DynamoDB update saving empty array as null

I'm using the Node.js package Dynamoose to handle DynamoDB requests in my web application.
Problem is when I try to update the item whenever the JSON object includes an empty array Dynamoose seems to set that to null. Or it could be DynamoDB for all I know.
Below is part of my schema that I'm using for this table.
var NoteSchema = new dynamoose.Schema({
_id: String,
details: Array
});
In the code below the variable body is set to {details: []}. I have confirmed this by running console.log(body);.
Note.update({
_id: searchid
}, body, function(err, note) {
if (err) {
console.log(err);
} else {
console.log(note);
}
});
Problem is inside that callback function when running console.log(note); details doesn't even show up at all. So it's null or undefined. In the Amazon Web Services again details doesn't exist at all for that entry.
What is so strange is when creating a new Note, setting details = [], and saving that, details is an empty array and works perfectly. So to me it seems like a specific problem with updating the record and setting that property to an empty array, since creating a record and setting that property to an empty array works perfectly.
How can I update the record and set details to an empty array?
Figured this out. Submitted this issue to the GitHub repo. Basically the following line (lib/Model.js about line 396) of code checks to see if the value is an array with length = 0. If so it will delete that JSON key before sending it to AWS.
if(val === null || val === undefined || val === '' || (Array.isArray(val) && val.length === 0)) {
I submitted a pull request using my fork. In that pull request I made the change to allow an optional JSON object parameter of options to be passed into the update function. This is the 3rd parameter of the update function and right before the callback function. If there is a key called emptyarrayallowed and that value is set to true then you that line above will get changed into the following.
if(val === null || val === undefined || val === '') {
For example in my example above changing the update function to the following will work (as long as you are using my fork or the pull request has been approved).
Note.update({_id: searchid}, body, {"emptyarrayallowed": true}, function(err, note) {
if (err) {
console.log(err);
} else {
console.log(note);
}
});
Let me know if you have any questions regarding this solution.
Small update on Charlie's answer. The functionality was merged as mentioned by Charlie. However, looks like the property name was renamed to allowEmptyArray from emptyarrayallowed.

check if JSON object exist in sessionstorage javascript

I am working on a site where some data is stored in the session. On the first page I need to check if the json object is already in the session.
This is the code that fails.
var passedTotaal = JSON.parse(sessionStorage.getItem('test totaal array'));
if(passedTotaal.hasOwnProperty('letterplaatnaam')){
//do something
}
When the JSON object exist it works else I get the following error:
Uncaught TypeError: Cannot read property 'hasOwnProperty' of null
I know this is because its empty.
I have looked at different stackoverflow questions but i couldn't find an answer
If there is any need for more information please let me know.
Try:
if(passedTotaal!=null && passedTotaal.hasOwnProperty('letterplaatnaam'))
var test = sessionStorage.getItem('test totaal array');
if (test) {
var passedTotaal = JSON.parse(test);
if(passedTotaal && passedTotaal.hasOwnProperty('letterplaatnaam')){
//do something
}
}
because getItem can return null as well

Duck Typing with JSON object - try/except?

In AngularJS, I have a api request that goes out and a JSON is returned. The JSON is stored as object data and I use data.Automation.Status to check the string in Status.
There are a few JSON errors that could a rise(after http 200 success with the json returned successfully):
The entire JSON could be returned a blank string ""
data JSON object could exist, but Automation JSON object could be undefined
Property Status of object Automation could be undefined or a blank string
Coming from python, all these possible situations could easily be handled in a try/except block.
Try:
do something with JSON
except (blah, blah)
don't error out because JSON object is broken, but do this instead
I see angular has $errorHandler service that can be modified with custom handlers. But I am not sure if this can be used in the same manner of duck typing that I am looking for.
How could I go about duck typing in AngularJS? Specifically, for the JSON object error scenerios mentioned in the list above?
How I am using data.Automation.Status at the moment:
if (iteration < Configuration.CHECK_ITERATIONS && data.Automation.Status !== "FAILED") {
iteration++;
return $timeout((function() {
return newStatusEvent(eventId, url, deferred, iteration);
}), Configuration.TIME_ITERATION);
} else {
err = data.Automation.StatusDescription;
return deferred.reject(err);
}
Here's how I came to a solution for the same problem.
It keeps it minimal, and all of the tests are grouped in one block.
$http.get('/endpoint1').success(function(res) {
try {
// test response before proceeding
if (JSON.stringify(res).length === 0) throw 'Empty JSON Response!';
if (!res.hasOwnProperty('Automation')) throw 'Automation object is undefined!';
if (!res.Automation.hasOwnProperty('Status') || res.Automation.Status !== 'SUCCESS')
throw 'Automation Status Failed!';
} catch (err) {
// handle your error here
console.error('Error in response from endpoint1: ' + err);
}
// if your assertions are correct you can continue your program
});
The best way that comes to mind to handle this situation would be using $parse since it handles undefined very well. You could do something like this:
$http.get('/endpoint1').success(function(res) {
try {
// test response before proceeding
if (angular.isUndefined($parse('Automation.Status')(res))) {
throw 'Automation Status Failed!';
}
} catch (err) {
// handle your error here
console.error('Error in response from endpoint1: ' + err);
}
// if your assertions are correct you can continue your program
});
You can see in this plunker how $parse handles your scenarios.
Depending on how complicated you want to get. If you want to use coffeescript, there's a nice ? operator: json.knownToExist.maybeExists?.maybeAlsoExists?() will never error out, and will only call maybeAlsoExists if it exists.
Otherwise, you could use typeof checks:
foo = {a: 1, b: 2}
typeof foo === 'object'
typeof foo.bar === 'undefined'
I'm under the impression that try/catch blocks in javascript are relatively expensive. So you probably want to test the json manually, especially if the different return values from your service are what you'd call 'normal' responses. Exceptions, IMO, should be used for exceptional occurrences, and not sanity checking.

Categories

Resources