I am trying to make a Parse.Cloud.httpRequest call, the job executes successfully but i am not getting any response. If i run the request on a RestClient it executes fine but for some reason it's not working in Parse Cloud Code. What am i doing wrong?
Parse.Cloud.job("Loader", function(request, status) {
var xmlreader = require('cloud/xmlreader.js');
var moment = require('cloud/moment.js');
var query = new Parse.Query("Codes");
query.each(function(a) {
var curDateMonth = moment().date();
var curMonth = moment().add(1, 'months').month();
var curYear = moment().year();
Parse.Cloud.httpRequest({
url: 'https://.....'
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
});
}).then(function() {
// Set the job's success status
status.success("Saved successfully.");
}, function(error) {
// Set the job's error status
status.error("Uh oh, something went wrong.");
});
});
Parse.Cloud.httpRequest() is an asynchronous function call. It doesn't block the thread, so your code keeps running to status.success("Saved successfully."); before you get the result from httpRequest().
Parse.Cloud.httpRequest() returns a Promise now, so you can simply chain them together.
Parse.Cloud.job("Loader", function(request, status) {
var xmlreader = require('cloud/xmlreader.js');
var moment = require('cloud/moment.js');
var query = new Parse.Query("Codes");
query.each(function(a) {
var curDateMonth = moment().date();
var curMonth = moment().add(1, 'months').month();
var curYear = moment().year();
return Parse.Cloud.httpRequest({
url: 'https://.....'
});
}).then(function(httpResponse) {
console.log(httpResponse.text);
status.success("Saved successfully. httpResponse: " + httpResponse.text);
}, function(error) {
// Set the job's error status
status.error("Uh oh, something went wrong.");
});
});
Edit
each() is something different, so please add the success callback to httpRequest directly.
Parse.Cloud.job("Loader", function(request, status) {
var allHttpResponseTexts = '';
var query = new Parse.Query("Codes");
query.each(function(a) {
return Parse.Cloud.httpRequest({
url: 'http://example.com',
success: function(httpResponse) {
// Process httpResponse.text here
allHttpResponseTexts += httpResponse.text.substr(0, 50);
}
});
}).then(function(httpResponse) {
status.success("Saved successfully. allHttpResponseTexts: " + allHttpResponseTexts);
}, function(error) {
status.error("Uh oh, something went wrong. " + error.code + ' - ' + error.message);
});
});
And the final result is:
Saved successfully. allHttpResponseTexts: <!doctype html> <html>
<head> <title>Example D...
Related
I'm currently running some tests with postman where I get a schema and try to validate my results against it.
I know the schema is not consistent with the response I'm getting but I wanted to know how is it possible to expand the results to give a bit more information.
so for example if I have a request like this:
GET /OBJ/{ID}
it just fails with the feedback:
Schema is valid:
expected false to be true
I was hoping to manage to get a bit more feedback in my newman report
this is an example of my test:
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// only preform tests if response is successful
if (pm.response.code === 200) {
var jsonData = pm.response.json();
pm.test("Data element contains an id", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.id).eql(pm.environment.get("obj_id"));
});
pm.test('Schema is valid', function() {
pm.expect(tv4.validate(jsonData, pm.globals.get("objSchema"))).to.be.true;
});
}
and this is how I run my tests:
const newman = require('newman');
newman.run({
insecure: true,
collection: require('../resources/API.postman_collection.json'),
environment: require('../resources/API.postman_environment.json'),
reporters: 'htmlextra',
reporter: {
htmlextra: {
export: './build/newman_report.html',
logs: true,
showOnlyFails: false,
darkTheme: false
}
}
}, function (err) {
if (err) {
throw err;
}
console.log('collection run complete!');
});
is there a way I can get more information about the validation failure?
I tried a few quick google search but have not come up to nothing that seemed meaningful
it's not exactly what I wanted but I managed to fix it with something like this:
// pre-check
var schemaUrl = pm.environment.get("ocSpecHost") + "type.schema";
pm.sendRequest(schemaUrl, function (err, response) {
pm.globals.set("rspSchema", response.json());
});
// test
var basicCheck = () => {
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response time is less than 200ms", function () {
pm.expect(pm.response.responseTime).to.be.below(200);
});
};
// create an error to get the output from the item validation
var outputItemError = (err) => {
pm.test(`${err.schemaPath} ${err.dataPath}: ${err.message}`, function () {
pm.expect(true).to.be.false; // just output the error
});
};
var itemCheck = (item, allErrors) => {
pm.test("Element contains an id", function () {
pm.expect(item.id).not.eql(undefined);
});
var Ajv = require('ajv');
ajv = new Ajv({
allErrors: allErrors,
logger: console
});
var valid = ajv.validate(pm.globals.get("rspSchema"), item);
if (valid) {
pm.test("Item is valid against schema", function () {
pm.expect(valid).to.be.true; // just to output that schema was validated
});
} else {
ajv.errors.forEach(err => outputItemError(err));
}
};
// check for individual response
var individualCheck = (allErrors) => {
// need to use eval to run this section
basicCheck();
// only preform tests if response is successful
if (pm.response.code === 200) {
var jsonData = pm.response.json();
pm.test("ID is expected ID", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.id).eql(pm.environment.get("nextItemId"));
});
itemCheck(jsonData, allErrors);
}
}
individualCheck(true);
just create a function to do an item test where I do a stupid assert.false to output each individual error in the schema path
I have been trying to implement Paypal's IPN using AWS Api Gateway to get an IPN handler url. the api is integrated with a Lambda function as the "receiver".
I have tested the api gateway url using Paypal's IPN simulator.It works for the first step and I get this message "IPN was sent and the handshake was verified".
My problem is now with the next step,where I have to send the recived message back to Paypal using HTTPS post. I have tried a number of times and keep getting this error:
{
"code": "ECONNREFUSED",
"errno": "ECONNREFUSED",
"syscall": "connect",
"address": "127.0.0.1",
"port": 443
}
I really would appreciate some help in getting this to work.
I'm using node.js 8.10.Here's my Lambda function:
exports.handler = (event, context, callback) => {
console.log('Received event:', JSON.stringify(event, null, 2));
// Return 200 to caller
console.log('sending 200 back to paypal');
callback(null, {
statusCode: '200'
});
// Read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
console.log('modifying return body...');
var body = 'cmd=_notify-validate&' + event.body;
callHttps(body, context);};
function callHttps(body, context) {
console.log('in callHttp()....');
var https = require('https');
var options = {
url: 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr',
method: 'POST',
headers: {
"user-agent": "Nodejs-IPN-VerificationScript"
},
body: body
};
const req = https.request(options, (res) => {
res.on('data', (chunk) => {
// code to execute
console.log("on data - can execute code here....");
});
res.on('end', () => {
// code to execute
console.log("on end - can execute code here....");
});
});
req.on('error', (e) => {
console.log("Error has occured: ", JSON.stringify(e, null, 2));
});
req.end();}
managed to sort it out.i was using url instead of breaking it down to host and path.here's the full code that worked for me:
exports.handler = (event, context, callback) => {
console.log('Received event:', JSON.stringify(event, null, 2));
// Return 200 to caller
console.log('sending 200 back to paypal');
callback(null, {
statusCode: '200'
});
callHttps(event.body, context);};
function callHttps(body, context) {
console.log('in callHttp()....');
// Read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
console.log('modifying return body...');
var bodyModified = 'cmd=_notify-validate&' + body;
var https = require('https');
var options = {
host: "ipnpb.sandbox.paypal.com",
path: "/cgi-bin/webscr",
method: 'POST',
headers: {
'user-agent': 'Nodejs-IPN-VerificationScript',
'Content-Length': bodyModified.length,
}
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
var result = '';
res.on('data', (d) => {
// get the result here
result += d;
});
res.on('end', (end) => {
// check the result
if (result === 'VERIFIED') {
// process the message
// split the message
var res = body.split("&");
// create an object
var paypalMessageObject = new Object();
// loop through split array
res.forEach(element => {
// split element
var temp = (element.toString()).split("=");
// add to the object
paypalMessageObject[temp[0]] = temp[1];
});
console.log('paypalMessageObject: ' + JSON.stringify(paypalMessageObject, null, 2));
var checkItems = {
payment_status: paypalMessageObject.payment_status,
mc_gross: paypalMessageObject.mc_gross,
mc_currency: paypalMessageObject.mc_currency,
txn_id: paypalMessageObject.txn_id,
receiver_email: paypalMessageObject.receiver_email,
item_number: paypalMessageObject.item_number,
item_name: paypalMessageObject.item_name
};
console.log('checkItems: ', JSON.stringify(checkItems, null, 2));
}
else { console.log('not verified, now what?'); }
});
});
req.on('error', (e) => {
console.log("Error has occured: ", JSON.stringify(e, null, 2));
});
req.write(bodyModified);
req.end();}
I'm creating mobile app using cordova+angular.js+onsenui.
What I want to do is to open pre-populated database, execute select statement and display result as list.
I use litehelpers/cordova-sqlite-ext plugin to manipulate database.
But when I run the app with iOS simulator and see the log in Safari console, "new transaction is waiting for open operation" is logged.
Console log is as below:
database already open: test.db
test1
new transaction is waiting for open operation
DB opened: test.db
My code(index.js) is the following.
angular.module('app').controller('listController', function ($scope) {
var items = [];
ons.ready(function() {
db = sqlitePlugin.openDatabase({name: "test.db", location: 2, createFromLocation: 1});
console.log('test1');
db.readTransaction(function(tx) {
console.log('test2');
var sql = "SELECT id, title, status FROM items";
tx.executeSql(sql, [], function(tx, response) {
for (var i = 0; i < response.rows.length; i++) {
var row = response.rows.item(i);
items.push({title:"Item Title", label:"6h", desc:row.title});
}
}, function(error) {
console.log('SELECT error: ' + error.message);
});
}, errorCB, successCB);
});
function successCB() {
$scope.itemTable = items;
$scope.$apply();
}
function errorCB(err) {
alert("Error processing SQL: "+err.code);
}
$scope.showDetail = function(item) {
console.log('showDetail');
myNavigator.pushPage("detail.html", {item: item});
};
});
Does anyone know how to resolve this?
I appreciate any suggestion and hint.
For someone who has encountered same problem,
I write my solution.
I changed plugin to the following.
litehelpers/Cordova-sqlite-storage
an-rahulpandey/cordova-plugin-dbcopy
And my code is like below.
function onDeviceReady() {
// Handle the Cordova pause and resume events
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener( 'resume', onResume.bind( this ), false );
dbcopy();
}
function dbcopy()
{
window.plugins.sqlDB.copy("test.db", 0, copysuccess, copyerror);
}
function copysuccess()
{
//open db and run your queries
//alert('copysuccess');
openDatabase();
}
function openDatabase()
{
db = window.sqlitePlugin.openDatabase({name: "test.db"});
}
function copyerror(e)
{
//db already exists or problem in copying the db file. Check the Log.
console.log("Error Code = "+JSON.stringify(e));
//e.code = 516 => if db exists
if (e.code == '516') {
openDatabase();
}
}
angular.module('app').controller('listController', function ($scope) {
var items = [];
ons.ready(function() {
if (db === null) {
openDatabase();
}
db.transaction(function(tx) {
var sql = "SELECT * FROM items;";
tx.executeSql(sql, [], function(tx, response) {
for (var i = 0; i < response.rows.length; i++) {
var row = response.rows.item(i);
items.push({title:row.title, label:row.label, desc:row.desc});
}
console.log("res.rows.item(0).title: " + response.rows.item(0).title);
}, errorCB);
}, errorCB, successCB);
});
function successCB() {
$scope.itemTable = items;
$scope.$apply();
}
function errorCB(err) {
alert("Error processing SQL: "+err.message);
}
$scope.showDetail = function(item) {
console.log('showDetail');
myNavigator.pushPage("detail.html", {item: item});
};
});
I am trying to generate a pdf with phantomjs from a page that's using highcharts. This is the script I am using
var port, server, service
system = require('system');
var page = require('webpage').create();
page.onError = function (msg, trace) {
console.log(msg);
trace.forEach(function(item) {
console.log(' ', item.file, ':', item.line);
})
}
var fs = require('fs');
function loadFile(name){
if(fs.exists(name)){
console.log(name+ " File exist");
return fs.open(name,"r");
}else {
console.log("File do not exist");
}
}
if (system.args.length !== 2) {
console.log('Usage: serverkeepalive.js <portnumber>');
phantom.exit(1);
} else {
port = system.args[1];
console.log('port: ' + port);
server = require('webserver').create();
service = server.listen(port, { keepAlive: true }, function (request, response) {
console.log('Request at ' + new Date());
console.log(JSON.stringify(request, null, 4));
console.log('ProjectId:' + request.headers.projectId)
var projectReportPage = 'http://localhost:55073/' + request.headers.projectId;
console.log(projectReportPage);
console.log(JSON.stringify(request.cookies, null, 4));
phantom.cookiesEnabled = true;
phantom.addCookie({
'name': 'hello', /* required property */
'value': 'helloFromPhantomJS', /* required property */
'domain': 'localhost', /* required property */
'expires': (new Date()).getTime() + 3600 /* <- expires in 1 hour */
});
console.log(JSON.stringify(phantom.cookies, null, 4));
page.paperSize = {
format: 'A4',
orientation: 'portrait',
margin:'1cm' };
page.open(projectReportPage, function (status) {
if (status !== 'success') {
console.log('FAIL to load the address');
} else {
console.log('Page obtained');
var reportName = 'report_' + request.headers.projectId + '.pdf';
page.evaluate( function(){$('h1').css('color', 'red');});
page.render(reportName);
var body = fs.absolute(reportName);
//var body = page.renderBase64('pdf');
// var fi = loadFile(reportName);
// var body = fi.read();
// var rawBody = fs.read(reportName);
// console.log(rawBody);
// var body = base64Encode(rawBody);
console.log(body);
response.statusCode = 200;
response.headers = {
'Cache': 'no-cache',
'Content-Type': 'application/pdf',
'Connection': 'Keep-Alive',
'Content-Length': body.length
};
response.write(body);
response.close();
}
});
console.log('After page open handler');
});
if (service) {
console.log('Web server running on port ' + port);
} else {
console.log('Error: Could not create web server listening on port ' + port);
phantom.exit();
}
}
When viewing the page, the chart looks like this:
http://i.imgur.com/kVImodv.png
This is what it looks like on the pdf:
http://i.imgur.com/vGon6vb.png
Any insights on why this happens would be appreciated!
The problem is that PhantomJS immediately takes a snapshot when the page is loaded. However, the Highcharts graph has an animation which builds up the graph.
This means the graph is not completely built up when PhantomJS is taking the snapshot. There are two possible solutions.
1. Skip the Highcharts animations
Add this to your graph configuration object.
plotOptions: {
series: {
animation: false
}
}
Source
2. Add a delay when taking a snapshot
page.open(address, function (status) {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 200);
}
Source
In my import photos script, I try to update a progressbar (Jquery UI) following a while loop with Ajax requests.
The JQueryUI progressbar, which is supposed to be displayed before the launch of ajax requests do it after. So I have the user feedback at the end of the execution of my while loop ... (The console shows me that these applications are running well, in the right order)
I thought about using live () or bind (), but I do not know how to test it ...
Here is my jquery code:
$(function() {
var percent_progressbar=0;
$('#myform').submit(function() {
$('#myform').hide();
$("#text_result").html("Import in progress : <span class='progression'>0/0</span>").show(10, function() {
$("#myprogressbar").progressbar({value:percent_progressbar});
$("#myprogressbar").show(10, function() {
if (jQuery.trim($("#id_src").val()).length!=0) {
// Total number of photos to import
$.ajax({
type : 'POST',
async : false,
url : '/nbphotos.php',
data : 'chem=mydir',
success : function(nbphotos){
if (nbphotos>0){
$(".progression").html("0"+" / "+nbphotos);
var finish=false;
var nb_photos_imported=0;
var ajax_done = false;
var resultat_ajax="";
// Variables envoyées en Ajax
var datas = desvariables;
while (nb_photos_imported < nbphotos) {
ajax_done = false;
$.ajax({
type : 'GET',
async : false,
url : '/traitement.php',
data : datas,
success : function(resultat){
resultat_ajax=resultat;
ajax_done=true;
nb_photos_imported++;
}
});
if (ajax_done==true){
if (resultat_ajax=="ok") {
percent_progressbar = Math.floor(nb_photos_imported*100/nbphotos);
$("#myprogressbar").progressbar("option", "value", percent_progressbar);
console.info("Succès ajax (resultat : OK) : "+percent_progressbar);
$(".progression").html(nb_photos_imported+" / "+nbphotos);
} else {
finish=true;
$("#text_result").html(ajax_done);
return false;
}
} else {
// ajax error => exit the while
console.info("Ajax execution error "+nb_photos_imported);
return false;
}
} // While
if (finish==true) {
$("#myprogressbar").hide('slow');
$('#text_result').html("Import of "+nb_photos_imported+" photos done.");
}
} else{
$("#text_result").html("No photo to import.");
$("#myprogressbar").hide(10);
$('#myform').show("slow");
}
}
});
}
});
}); // callback #text_result.show()
return false;
});
});
Here is my new code. The console log show the progression of the percentage, the photos are imported, but I still have the display at the end. If I put a breakpoint with me debugging tool somewhere in the loop, the display is refreshing and everything is OK...
$(function () {
$("#myprogressbar").show();
var RetourNbPhotos = "";
var RetourImported = "";
var fini = false;
var percent_progressbar = 0;
var nb_photos_imported = 0;
var datas = desvariables; // datas sent with ajax
// Number of photos to import
function NbPhotoAjax() {
return $.ajax({
type: 'POST',
async: false,
url: '/boutique/modules/importimageswithiptc/ajax-nbphotos.php',
data: 'chem=$cheminimport',
success: function (nbphotos) {
RetourNbPhotos = nbphotos;
}
});
}
// Photo Ajax Import
function ImportPhotoAjax() {
$("#text_result").html("Import in progress : <span class='progression'>0/0</span>").show();
// RetourImported = "";
return $.ajax({
type: 'GET',
async: false,
url: '/boutique/modules/importimageswithiptc/ajax-traitement.php',
data: datas,
success: function (resultat) {
RetourImported = resultat;
}
});
}
$("#myprogressbar").progressbar({
value: percent_progressbar
});
$('#generator').submit(function () {
$('#generator').hide();
if (jQuery.trim($("#id_product_src").val()).length != 0) {
$.when(NbPhotoAjax()).then(function () {
if (RetourNbPhotos > 0) {
while (nb_photos_imported < RetourNbPhotos) {
$.when(ImportPhotoAjax()).then(function () {
nb_photos_imported++;
if (RetourImported == "ok") {
percent_progressbar = Math.floor(nb_photos_imported * 100 / RetourNbPhotos);
$("#myprogressbar").progressbar("option", "value", percent_progressbar);
console.info("Success : " + percent_progressbar + "%");
$(".progression").html(nb_photos_imported + " / " + RetourNbPhotos);
} else {
fini = true;
$("#text_result").html("ajax_reussi");
return false;
}
}).fail(function () {
// ajax error => exit the while
console.info("Ajax execution error " + nb_photos_imported);
return false;
});
} // While
if (fini == true) {
$("#myprogressbar").hide('slow');
$('#text_result').html("Import of " + nb_photos_imported + " photos done.");
}
} else {
$("#text_result").html("No photo to import.");
$("#myprogressbar").hide(10);
$('#generator').show("slow");
}
});
}
return false;
});
});