0

With some research and some of your help I was able to create and comment some code I believe will help people understand Javascript Promises more clearly.

My question is, when I try to trigger a catch by intentionally misspelling the JSON file name, nothing happens. No error. No continue. Nothing. Why?

Why doesn't...

else reject( new Error( 'We could not load the URI: ' + uri ) );

...gets thrown?

URL for you to visualize without cross origin issues when getting JSON file.

Test Page

Content of resultset.json

[
  {
    "PK_USER_TIME_LOG_ID": 120,
    "CLIENT_ID": 111,
    "PROJECT_ID": 222,
    "USER_ID": 465605,
    "UTL_DTSTAMP": "2018-01-15 17:56:06",
    "UTL_LATITUDE": "40.61105890",
    "UTL_LONGITUDE": "-111.89993530",
    "UTL_EVENT": "CLOCK IN",
    "UTL_ACTION": "MEETING",
    "UTL_DURATION": 3
  },
  {
    "PK_USER_TIME_LOG_ID": 122,
    "CLIENT_ID": 111,
    "PROJECT_ID": 222,
    "USER_ID": 465605,
    "UTL_DTSTAMP": "2018-01-15 17:56:19",
    "UTL_LATITUDE": "40.61105890",
    "UTL_LONGITUDE": "-111.89993530",
    "UTL_EVENT": "CLOCK IN",
    "UTL_ACTION": "TRAVEL",
    "UTL_DURATION": 5
  },
  {
    "PK_USER_TIME_LOG_ID": 123,
    "CLIENT_ID": 111,
    "PROJECT_ID": 222,
    "USER_ID": 465605,
    "UTL_DTSTAMP": "2018-01-15 17:56:24",
    "UTL_LATITUDE": "40.61105890",
    "UTL_LONGITUDE": "-111.89993530",
    "UTL_EVENT": "CLOCK IN",
    "UTL_ACTION": "TEAR OUT",
    "UTL_DURATION": 3
  }
]

Javascript Promise Code Updated 1/18/2018

$(document).ready(function() {

console.log('1. Document is ready.');

// Run the App.
runApplication();
});

// anything we would like to run *** BEFORE *** getURI( obj ) function is called.
var runFirst = function runFirst() {

console.log( '2. Promise > runFirst() function called.' );
};


// We create a variable called getURI and assign it a function getURI( uri )
var getURI = function getURI( uri ) {

console.log('3. Promise > getURI( uri ) function called.');

// We then create a new Promise (Which is a wrapper..) to return.
return new Promise( function( resolve, reject ) {

// Our JSON request..
$.getJSON( uri, function( data ) {

// if data is not defined OR an empty string...
if (data =! true || data.length < 1) {

// Create a new error and...
var error = new Error();

// Inject an error status code of 204.
error.status = 204;

// Reject Promise with custom error.
reject( error );

} else {

// Continue...
resolve( data );
}

}).fail( reject );
// Invoke Promise Reject so we can handle the Ajax .fail() by status code.

}); // End promise.
};


// obj edit In Progress.
var processData = function processData( obj ) {

console.log( '3.2 Promise > processData( obj ) function called.' );

// Parse array of arrays if we have to. (For resultSet containing more than one record..)
$.each(obj, function( i, row ) {

// DO...

// Get current row.USER_ID from current row.
console.log('3.2.1 Get: row.USER_ID = '+ row.USER_ID);

// AND OR..
// Set current row.USER_ID to something else..
row.USER_ID = 'something else..';

// AND OR..
// Push a new_element into current row..
row.new_element = 'something new!';

//THEN...

// Get updated row.USER_ID from current row.
console.log('3.2.2 Set: '+ row.USER_ID);

}); // End jQuery for each loop

// Return Original and/or Augmented fectched object.
return Promise.resolve(obj);
};


// obj Done editing. Now we render it. (Display the most up to date version of it.)
var renderData = function renderData( obj ) {

console.log( '3.3 Promise > renderData( obj ) function called.' );
//console.log( obj );

// Return fectched object after being proccessed by processData.
return Promise.resolve(obj);
};


// anything we would like to run *** AFTER *** our getURI( uri ) function is called.
var runLast = function runLast( obj ) {

console.log( '3.4 Promise > runLast() function called.' );
console.log( '3.5 Promise > Successful $.getJSON() response received.' );

// Return fectched object after being proccessed by renderData.
return Promise.resolve(obj);
};

// error handling for $.getJSON() and anything else.
var handleError = function handleError( error ) {

console.log( 'Error - Promise > handleError( error ) function called.' );
console.log( 'Error - We found an error while fetching and/or augmenting some data.' );

// Error if $.getJSON() is status: 204 No Content.
if (error.status == 204) {

console.error( '$.getJSON() .status: ' + error.status + ' - No Content.');
return;
}

// Error if $.getJSON() is status: 404 Not Found.
if (error.status == 404) {

console.error( '$.getJSON() .status: ' + error.status + ' - Not Found.');
return;
}

// Error unknown...
console.log(error);

};


// We create a variable called runApplication and assign it a function runApplication()
var runApplication = function runApplication() {

console.log( '1.1 runApplication() function called.' );

// Similar to Ajax beforeSend()..
runFirst();

// getURI request execution order...
getURI( 'resultset.json' ) // entering Promise...
.then( processData )      // process the data...
.then( renderData )       // render the processed data...
.then( runLast )          // finalize...
.catch( handleError );    // catch our Ajax and Custom errors.)
};
suchislife
  • 4,251
  • 10
  • 47
  • 78
  • It is an array of arrays. – suchislife Jan 18 '18 at 03:20
  • It's an Array of Objects, but `row` would still be one of those Objects, so I removed my comment. Sorry for the confusion. – StackSlave Jan 18 '18 at 03:25
  • Ok. Can you post an update example of my code with where I need to throw it? I must be placing it wrong. I was under the impression the error gets thrown when the promise rejects. The promise reject then triggers a catch which then uses errorHandle to ideally handle the error. This is not happening. – suchislife Jan 18 '18 at 03:42
  • you can try console.log("something") in else block to debug. I think jQuery silently ignore if json string has error syntax. Reference: http://api.jquery.com/jquery.getjson/ – Viet Phan Jan 18 '18 at 03:53
  • The function that is the second argument to `.getJSON` doesn't execute at all if there is no success. That's like the `success` function. – StackSlave Jan 18 '18 at 03:59
  • Ok. What is the syntax error in my JSON that causes it to fail silently? It is generated by PHP's json_econde. The link to it is in the question – suchislife Jan 18 '18 at 04:00
  • Also, $.get returns silent too. – suchislife Jan 18 '18 at 04:01
  • When you change the URL to one that is not `success`ful then both resolve and reject don't fire, since you wrapped them within your `success` function. – StackSlave Jan 18 '18 at 04:06

1 Answers1

2

If you want catch ajax error, add method .fail after. As doc says, $.getJSON has silent errors..

$(document).ready(function() {
console.log('1. Document is ready.');
});
// We create a variable called getURI and assign it a function getURI( uri )
var getURI = function getURI( uri ) {
    // We then create a new Promise (Which is wrapper..) to return.
    return new Promise( function( resolve, reject ) {
        // Asynch request for JSON data... (Because that's what we are getting from the server.)
        // ajax commented due to snippet
        $.getJSON( uri, function( data ) {
            // if we got something, resolve promise
            if ( data ) resolve( data );
            // else reject promise and throw an Error.
            else reject( new Error( 'We could not load the URI: ' + uri ) );
        }).fail(reject)
        // End get.
    }); // End promise.
};
// anything we would like to run *** BEFORE *** getURI( obj ) function is called.
var runFirst = function runFirst() {
    console.log( '3.1 Promise > runFirst() function called.' );
};
// obj being edited. Status in progress.
var processData = function processData( obj ) {
    console.log( '3.2 Promise > processData( obj ) function called.' );
        // Parse array of arrays if we have to. (For resultSet containing more than one record..)
        $.each(obj, function( row_idx, row ) {
            // DO...
            // Get current row.USER_ID from current row.
            console.log('3.2.1 Get: '+ row.USER_ID);
            // AND OR..
            // Set current row.USER_ID to something else..
            row.USER_ID = 'something else..';
            // AND OR..
            // Push new row.new_element to something new!
            row.new_element = 'something new!';
            //THEN..
            // Get updated row.USER_ID from current row.
            console.log('3.2.2 Set: '+ row.USER_ID);
        }); // END jQuery for each loop
        // Return Formated Object.
        return Promise.resolve(obj);
};
// obj Done editing. Now we render it. (Display the most up to date version of it.)
var renderData = function renderData( obj ) {
    console.log( '3.3 Promise > renderData( obj ) function called.' );
    //console.log( obj );
    return Promise.resolve(obj);
};
// anything we would like to run *** AFTER *** our getURI( uri ) function is called.
var runLast = function runLast(obj) {
    console.log( '3.4 Promise > runLast() function called.' );
    return Promise.resolve(obj);
};
// finally handleError( error ); how we handle our catch function.
var handleError = function handleError( error ) {
    console.log( '3.x Promise > handleError( error ) function called.' );
    console.log( '3.x We found an error while fetching and augmenting some data.' );
    console.error( error );
};
// We create a variable called runApplication and assign it a function runApplication()
var runApplication = function runApplication() {
    // Similar to Ajax beforeSend()..
    runFirst();
    // getURI request execution order...
    getURI( 'resultset.json' )
        .then( processData )
        .then( renderData )
        .then( runLast )
        .catch( handleError );
};
// I think you can guess what this does.
runApplication();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
bigless
  • 2,849
  • 19
  • 31
  • Ok. What is the syntax error in my JSON that causes it to fail silently? It is generated by PHP's json_econde. – suchislife Jan 18 '18 at 03:59
  • Also, $.get returns silent too. – suchislife Jan 18 '18 at 04:01
  • The json I have is an array of objects. But this causes a syntax error? – suchislife Jan 18 '18 at 04:03
  • You were talking about misspeled filename of json, it leads probably to 404. And this error is catched by fail method. Your page load json with status code 200 so.. – bigless Jan 18 '18 at 04:05
  • I've noticed you added return Promise.resolve(obj); instead of return obj. Why? (other than the obvious..) – suchislife Jan 18 '18 at 04:57
  • In this case, it is same. [You can find detailed answers to your question here](https://stackoverflow.com/questions/27715275/whats-the-difference-between-returning-value-or-promise-resolve-from-then) – bigless Jan 18 '18 at 05:10
  • 1
    @Vini btw if you want wrap async func into promise, this is ecma6 shorthand: `return new Promise((resolve, reject) => $.getJSON(uri, resolve).fail(reject))` – bigless Jan 18 '18 at 05:27
  • I have updated the code to reflect 204 & 404 error handling. Hopefully this will do. – suchislife Jan 18 '18 at 20:39