Error occurs, API SoundCloud Custom Player - json

Hi I'm trying to catch an Error when it occurs but I have a problem with Json
When the track is loading perfectly I received a success answer but in a crash I have nothing
$.getJSON(apiUrl, function(data, error) {
index += 1;
if(data.tracks){
playerObj.tracks = playerObj.tracks.concat(data.tracks);
}else if(data.duration){
data.permalink_url = link.url;
playerObj.tracks.push(data);
}else if(data.creator){
links.push({url:data.uri + '/tracks'});
}else if(data.username){
if(/favorites/.test(link.url)){
links.push({url:data.uri + '/favorites'});
}else{
links.push({url:data.uri + '/tracks'});
}
}else if($.isArray(data)){
playerObj.tracks = playerObj.tracks.concat(data);
}
if(links[index] && (index % 18) != 0){
var mod = index % 18;
loadUrl(links[index]);
}else{
playerObj.node.trigger({type:'onTrackDataLoaded', playerObj: playerObj, url: apiUrl});
if (links[index]) {
loadMoreTracksData($player, links, key, index);
}
}
}).success(function() { console.log("second success"); }).error(function() { console.log("error"); });
Does anyone know how to listen correctly Errors in this Api.

Assuming you're using a version of jQuery > 1.5 the below is a structure that would be better suited.
The fail method will only be called when an applicable HTTP code is returned from the server (e.g 500 / 404 / 400) not simply when an empty set of data is returned, but with a successful HTTP 200 response.
var index = 0;
var processResponse = function(data) {
index += 1;
if(data.tracks){
playerObj.tracks = playerObj.tracks.concat(data.tracks);
}else if(data.duration){
data.permalink_url = link.url;
playerObj.tracks.push(data);
}else if(data.creator){
links.push({url:data.uri + '/tracks'});
}else if(data.username){
if(/favorites/.test(link.url)){
links.push({url:data.uri + '/favorites'});
}else{
links.push({url:data.uri + '/tracks'});
}
}else if($.isArray(data)){
playerObj.tracks = playerObj.tracks.concat(data);
}
if(links[index] && (index % 18) != 0){
var mod = index % 18;
loadUrl(links[index]);
}else{
playerObj.node.trigger({type:'onTrackDataLoaded', playerObj: playerObj, url: apiUrl});
if (links[index]) {
loadMoreTracksData($player, links, key, index);
}
}
var processError = function(error){
console.log("Error:" + error);
}
$.getJSON(apiUrl)
.done(function(data){ processResponse(data); })
.fail(function(error){ processError(error); })
.complete(function(xhr, status) {console.log(status);};

Related

How change display value/color td based on JSON

I'm working on an app where I get a json via an ajax call. This json contains objects where you get a certain status code per extension (1 = online, 2, is ringing, 3 = busy)
How can I ensure that the value that I get back is converted to the text (preferably with a different color of the )
So when I get a 1 back I want it to show Online, and with a 2 Ring etc
$.ajax({
type:'GET',
url: url,
dataType: 'json',
error: function(jqXHR, exception) {ajax_error_handler(jqXHR, exception);},
success: function(data){
// console.log(JSON.parse(data.responseText));
// console.log(JSON.parse(data.responseJSON));
console.log(data['entry']);
var event_data = '';
$.each(data.entry, function(index, value){
/* console.log(data['entry']);*/
event_data += '<tr>';
event_data += '<td>'+value.extension+'</td>';
event_data += '<td>'+value.status+'</td>';
<!--event_data += '<td>'+value.registration+'</td>';-->
event_data += '</tr>';
});
$("#list_table_json").append(event_data);
},
error: function(d){
/*console.log("error");*/
alert("404. Please wait until the File is Loaded.");
}
});
Thanks in advance!
I have change the code
function get_blf() {
$.ajax({
type:'GET',
url: url,
dataType: 'json',
error: function(jqXHR, exception) {ajax_error_handler(jqXHR, exception);},
success: function(data){
$.each(data.entry, (index, value) => {
const tableRow = document.createElement('tr');
const tdExtension = document.createElement('td');
extension.textContent = value.status;
const tdStatus = document.createElement('td');
if (value.status == 3) status.textContent = 'Busy';
if (value.status == 2) status.textContent = 'Ringing';
if (value.status == 1) status.textContent = 'Online';
tdStatus.classList.add(`status-${value.status}`);
tableRow.appendChild(tdExtension);
tableRow.appendChild(tdStatus);
$('#list_table_json').append(tableRow);
}
});
}
}
and add the css, but now i can't get any values back. but now i can't get any values back. (sorry I'm fairly new to javascript)
Please use the DOM API
One way of getting colors would be to use CSS classes for the status:
// js
...
$.each(data.entry, (index, value) => {
const tableRow = document.createElement('tr');
const tdExtension = document.createElement('td');
extension.textContent = value.extension;
const tdStatus = document.createElement('td');
if (value.status == 3) status.textContent = 'Busy';
if (value.status == 2) status.textContent = 'Ringing';
if (value.status == 1) status.textContent = 'Online';
tdStatus.classList.add(`status-${value.status}`);
tableRow.appendChild(tdExtension);
tableRow.appendChild(tdStatus);
$('#list_table_json').append(tableRow);
});
...
// css
.status-1 {
color: green;
}
.status-2 {
color: red;
}
.status-3 {
color: orange;
}
I finally got the script working. I am now trying to build in a polling, however I see that the ajax call is executed again and the array is fetched. However, the table is not refreshed but a new table is added, does anyone know a solution for this?
code I'm using now for the repoll is
function repoll(poll_request, poll_interval, param=null) {
if (poll_interval != 0) {
if (window.timeoutPool) {
window.timeoutPool.push(setTimeout(function() { poll_request(param); }, poll_interval));
}
else {
setTimeout(function() { poll_request(param); }, poll_interval);
}
}
else {
log_msg('Poll cancelled.');
}
}
tableRow.appendChild(tdExtension);
tableRow.appendChild(tdNr);
tableRow.appendChild(tdStatus);
$('#list_table_json').append(tableRow);
});
repoll(get_blf, poll_interval_blf);

Fetching data from API but no data are being displayed in html

I'm trying to fetch a specific set of data from an API as shown in the code below. Fetching only the football home teams' name and displaying it into a table.
I am getting no errors but no data is being shown in my table.
xhr.onreadystatechange = function()
{
if(this.readyState == 4 && this.status == 200)
{
//document.getElementById('text').innerHTML = this.responseText;
const obj = JSON.parse(this.responseText);
for (var i=0; i<obj.length; i++)
{
var row = $('<tr><td>' + obj.response[i].teams.home.name + '</td></tr>');
$('#myTable').append(row);
}
}
}
xhr.onerror = function()
{
console.log('Request Error');
}
xhr.send();
}
when doing console.log(obj)
you could do something like this
xhr.onreadystatechange = function()
{
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status == 200)
{
//document.getElementById('text').innerHTML = this.responseText;
const obj = JSON.parse(xhr.responseText);
for (var i=0; i<obj.response.length; i++)
{
var row = $('<tr><td>' + obj.response[i].teams.home.name + '</td></tr>');
$('#myTable').append(row);
}
}
}
xhr.onerror = function()
{
console.log('Request Error');
}
xhr.send();

AngularJS - Weird error with sending and deleting JSON data from cache in while loop?

The loop is behaving strange where the alerts are firing out of order and the JSON data is being sent all at the same exact time. I do not understand why this is happening at all. I have been struggling with this for too long now and any help would be insanely appreciated!
Submitting with 3 cached JSON objects, the sequence goes:
Alert "should be second"
Alert "should be second"
Alert "should be second"
Alert "{#xmlns:ns3":"url}"
Alert "should be first"
Alert "0posted"
Then successfully sends all three JSON objects to the database at the same time.
The cachePostCount is now set to zero
app.controller('FormCtrl', function($scope, $filter, $window, getData, Post, randomString) {
// Get all posts
$scope.posts = Post.query();
// Our form data for creating a new post with ng-model
$scope.postData = {};
$scope.$on('updateImage', function () {
$scope.postData.attachment = getData.image;
});
$scope.postData.userid = "Mango Farmer";
$scope.postData.uuid = randomString(32); //$scope.genUUID();
$scope.$on('updateGPS', function () {
$scope.postData.gps = getData.gps;
});
$scope.postData.devicedate = $filter('date')(new Date(),'yyyy-MM-dd HH:mm:ss');
$scope.newPost = function() {
var post = new Post($scope.postData);
var postCount = window.localStorage.getItem("cachedPostCount");
if(typeof postCount == 'undefined' || postCount == null){
postCount = 1;
window.localStorage.setItem("cachedPostCount", postCount);
}
else {
postCount ++;
window.localStorage.setItem("cachedPostCount", postCount);
}
window.localStorage.setItem("post" + postCount, JSON.stringify(post));
while (postCount > 0) {
var curCacheObj = new Post(JSON.parse(window.localStorage.getItem("post" + postCount) || '{}'));
curCacheObj.$save().then(function(response) {
var servResponse = JSON.stringify(response);
alert(servResponse);
if (servResponse.indexOf("#xmlns:ns3") > -1) {
alert("should be first");
window.localStorage.removeItem("post" + postCount);
alert(window.localStorage.getItem("cachedPostCount") + "posted");
$window.location.href = 'success.html';
}
else {
alert("Unable to post at this time!");
}
});
alert("should be second");
postCount --;
window.localStorage.setItem("cachedPostCount", postCount);
}
};
$save() is an asynchronous operation and is guaranteed to not happen until after the next tick in the event loop, which will occur after alert("should be second"); occurs. You should place this alert (and any other logic) that relies on that ordering inside the then() function or chain on another then() function and put it in there instead, like so:
curCacheObj.$save().then(function(response) {
var servResponse = JSON.stringify(response);
alert(servResponse);
if (servResponse.indexOf("#xmlns:ns3") > -1) {
alert("should be first");
window.localStorage.removeItem("post" + postCount);
alert(window.localStorage.getItem("cachedPostCount") + "posted");
$window.location.href = 'success.html';
}
else {
alert("Unable to post at this time!");
}
}).then(function() {
alert("should be second");
postCount --;
window.localStorage.setItem("cachedPostCount", postCount);
});
The problem was that .$save() does not like while loops (maybe because it is an asynchronous function as mentioned previously). I recreated the effect of a while loop with a function using an if statement that will fire the function again if the cached postCount still has data as follows:
$scope.submitAndClearCache = function() {
var postCount = window.localStorage.getItem("localPostCount");
var curCacheObj = new Post(JSON.parse(window.localStorage.getItem("post" + postCount) || '{}'));
if (postCount != 0) {
curCacheObj.$save().then(function(response) {
alert(response);
alert("Post " + postCount + " sent!");
}).then(function() {
postCount --;
window.localStorage.setItem("localPostCount", postCount);
postCount = window.localStorage.getItem("localPostCount");
$scope.submitAndClearCache();
});
}
};
$scope.addCachePost = function() {
var frmData = new Post($scope.postData);
var postCount = window.localStorage.getItem("localPostCount");
postCount ++;
window.localStorage.setItem("localPostCount", postCount);
window.localStorage.setItem("post" + postCount, JSON.stringify(frmData));
};
This technique works, it just seems weird.

how to make a while loop in nodejs to be a series

My Nodejs Code:
i am trying to download files (excel) from a server and parse those excel files and from that data store only required data into mysql database i may download multiple files for that my loop may get interrupted so how to do my below code to run in a series of synchronous way
var r=0;
if (issue.fields.attachment != '') {
while (typeof issue.fields.attachment[r] != "undefined") {
if (typeof issue.fields.attachment[r].content != "undefined") {
var url = issue.fields.attachment[r].content;
request({
method: "GET",
"url": url,
"headers": { "Content-Type": "application/json", }
}, function(err, data, body) {
console.log('file downloading');
}).pipe(fs.createWriteStream('file.xlsx'));
console.log('file downloaded');
parseXlsx('file.xlsx', function(err, data) {
var i, j, k = 1, l = 0, m = 0, n = 0;
console.log('parseXlsx cmpleted');
while (data[i] != undefined) {
if (data[i][j] != '' || data[i][k] != '' || data[i][l] != '') {
var query = connection.query('insert into IP values ("' + data[i][j] + '","' + data[i][k] + '","' + data[i][l] + '","' + data[i][m] + '")',
function(error, results, fields) {
});
}
i++;
}
});
r++;
console.log('rvalue' + r);
}
}
}
I (very quickly, so it probably has errors) rewrote this using async.forEachOfSeries to iterate over your attachments. I used async.forEachOf for the database writes as I don't see a need for them to be in series.
var async = require('async');
if (issue.fields.attachment != '') {
async.forEachOfSeries(issue.fields.attachment,function(attachment,r,callback){
if (typeof issue.fields.attachment[r].content != "undefined") {
var url = issue.fields.attachment[r].content;
var ws = fs.createWriteStream('file.xlsx');
request({ method: "GET", "url": url, "headers": { "Content-Type": "application/json" }
}, function(err, data, body) {
console.log('file downloading');
}).pipe(ws);
ws.on('finish',function() {
console.log('file downloaded');
parseXlsx('file.xlsx', function (err, data) {
var i, j, k = 1, l = 0, m = 0, n = 0;
for (i = 0; i < 15; i++) {
for (j = 0; j < 15; j++) {
if (regex.test(data[i][j])) {
k = 0;
break;
}
}
if (k == 0)
break;
}
for (k = 0; k < 15; k++) {
if (regex1.test(data[i][k])) {
break;
}
}
for (l = 0; l < 15; l++) {
if (regex2.test(data[i][l])) {
break;
}
}
for (m = 0; m < 15; m++) {
if (regex2.test(data[i][m])) {
break;
}
}
i = i + 1;
console.log('parseXlsx completed');
async.forEachOf(data,function(row,i,_callback){
if(i===0)return _callback();
if (data[i][j] != '' || data[i][k] != '' || data[i][l] != '') {
var query = connection.query('insert into IP values ("' + data[i][j] + '","' + data[i][k] + '","' + data[i][l] + '","' + data[i][m] + '")',
function (error, results, fields) {
if(error){
//Decide if you want to stop writing rows if one insert fails, if so uncomment next line
//return _callback(error);
}
return _callback();
});
}
},function(err){
if(err){
//decide if you want to stop the whole process if the database errored, if so, uncomment next line
//return callback(err);
}
callback();
});
});
});
ws.on('error',function(err) {
//There was an error writing the file to disk, but I assume you want to continue anyway so I'm calling callback()
//If you want to stop processing, call callback(new Error('Failed writing to disk'));
return callback();
});
}
});
}

Catching exceptions thrown by Swagger

I'm new at fumbling with Swagger, so I might be asking a silly question. Is it in any way possible to prevent the site from crashing whenever it is "unable to read from api"?
My site is working most of the time, but if there for some reason is an api that is unreadable (or just unreachable) swagger just stop working. It still displays the api's it managed to reach, but all functionality is completely gone its not even able to expand a row.
To summarize:
How do I prevent swagger from crashing, when one or more API's is unreadable and returns something like this:
Unable to read api 'XXXX' from path
http://example.com/swagger/api-docs/XXXX (server
returned undefined)
Below is my initialization of Swagger:
function loadSwagger() {
window.swaggerUi = new SwaggerUi({
url: "/frameworks/swagger/v1/api.json",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function (swaggerApi, swaggerUi) {
log("Loaded SwaggerUI");
if (typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
realm: "your-realms",
appName: "your-app-name"
});
}
$('pre code').each(function (i, e) {
hljs.highlightBlock(e);
});
},
onFailure: function (data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
sorter: "alpha"
});
$('#input_apiKey').change(function () {
var key = $('#input_apiKey')[0].value;
log("key: " + key);
if (key && key.trim() != "") {
log("added key " + key);
window.authorizations.add("api_key", new ApiKeyAuthorization('api_key', key, 'header'));
}
});
$('#apiVersionSelectID').change(function () {
var sel = $('#apiVersionSelectID').val();
window.swaggerUi.url = sel;
$('#input_baseUrl').val(sel);
$('#explore').click();
});
window.swaggerUi.load();
};
I was searching for a solution to this problem too but could not find one. Here is a quick hack i did to solve the problem. Hope it can be of help to someone who is having the same trouble.
In swagger-client.js Find the function error: function (response) {
I replaced the return api_fail with addApiDeclaration to make it draw the api with some limited information even when it fails. I send in a dummy api json object with the path set to "/unable to load ' + _this.url. I send in an extra parameter that can be true or false, where true indicates that this is a failed api.
Old code:
enter cerror: function (response) {
_this.api.resourceCount += 1;
return _this.api.fail('Unable to read api \'' +
_this.name + '\' from path ' + _this.url + ' (server returned ' +response.statusText + ')');
}
New code
error: function (response) {
_this.api.resourceCount += 1;
return _this.addApiDeclaration(JSON.parse('{"apis":[{"path":"/unable to load ' + _this.url + '","operations":[{"nickname":"A","method":" "}]}],"models":{}}'), true);
}
I modified the addApiDeclaration function in the same file to display a different message for a failed api by first adding a secondary parameter to it called failed and then an if statement that check if failed is true and then change the name of the api to "FAILED TO LOAD RESOURCE " + this.name. This adds the FAILED TO LOAD RESOURCE text before the failed api.
Old code
SwaggerResource.prototype.addApiDeclaration = function (response) {
if (typeof response.produces === 'string')
this.produces = response.produces;
if (typeof response.consumes === 'string')
this.consumes = response.consumes;
if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0)
this.basePath = response.basePath.indexOf('http') === -1 ? this.getAbsoluteBasePath(response.basePath) : response.basePath;
this.resourcePath = response.resourcePath;
this.addModels(response.models);
if (response.apis) {
for (var i = 0 ; i < response.apis.length; i++) {
var endpoint = response.apis[i];
this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces);
}
}
this.api[this.name] = this;
this.ready = true;
if(this.api.resourceCount === this.api.expectedResourceCount)
this.api.finish();
return this;
};
New code
SwaggerResource.prototype.addApiDeclaration = function (response, failed) {
if (typeof response.produces === 'string')
this.produces = response.produces;
if (typeof response.consumes === 'string')
this.consumes = response.consumes;
if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0)
this.basePath = response.basePath.indexOf('http') === -1 ? this.getAbsoluteBasePath(response.basePath) : response.basePath;
this.resourcePath = response.resourcePath;
this.addModels(response.models);
if (response.apis) {
for (var i = 0 ; i < response.apis.length; i++) {
var endpoint = response.apis[i];
this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces);
}
}
if (failed == true) {
this.name = "FAILED TO LOAD RESOURCE - " + this.name;
}
this.api[this.name] = this;
this.ready = true;
if(this.api.resourceCount === this.api.expectedResourceCount)
this.api.finish();
return this;
};