I'm trying to put a 1 second delay using setTimeout(()=>{},1000) in the Pre-request Script for a Postman POST call.
var moment = require('moment');
var tap1TimeStr = pm.environment.get("now");
var tap1TimeMoment = moment(tap1TimeStr,"YYYY-MM-DDTHH:mm:ss");
var expTap2Time = tap1TimeMoment.add(2, 'minutes').format("YYYY-MM-DDTHH:mm:ss");
console.log("Tap 2 timestamp should be: " + expTap2Time);
var timestamp;
var timecheck = false;
while(!timecheck)
{
setTimeout(() => {},1000);
timecheck = moment.utc().isSame(expTap2Time);
console.log("timecheck: " + timecheck);
timestamp = moment.utc().format("YYYY-MM-DDTHH:mm:ss");
}
console.log("Timestamp is now: " + timestamp);
pm.environment.set("now", timestamp);
But it doesn't seem to work and I can see that the console.log line is being printed far more frequently than 1sec. And the exercise here is to send the "Tap 2" POST exactly 2mins after the first POST (tracked by the 'now' variable). Also, it seems like Postman takes a fair bit of time before it even starts executing this particular script.
Edit: The main requirement here is to send the "Tap 2" POST request exactly 2mins AFTER the "Tap 1" POST request. HOW best to implement that? Espcially if setTimeout() is non-blocking and thus probably can't be used in a loop.
Anyone has any ideas?
setTimeout() takes a callback function which is executed after the specified delay so only what happens in the callback function will happen after that delay.
setTimeout(() => {
console.log("This will be executed after 1 second");
}, 1000);
console.log("This will immediately be executed");
setTimeout() is asynchronous and non-blocking so JavaScript will call set timeout but not wait for 1 second for it to return and instead immediately move on to the next instruction. Only after that 1 second has passed the callback passed to setTimeout() will be scheduled and executed. Have a look at this YouTube video for a good explanation of what's going on.
Related
I tried to look everywhere, but no luck so far. I have a collection with 6 requests that run automatically, but I need the last request to run only once at the end of the last iteration.
I tried to use this code in Pre-request Script of Request 5
if (pm.info.iteration === 0) {
postman.setNextRequest("Request 6")
} else {
postman.setNextRequest("Request 1")
}
and expected that the Request 6 would run only once after there is no more iteration to run, but I am doing something wrong since it is still not working.
you kind of mixed up pm.info.iterationCount and pm.info.iteration:
pm.info.iteration The value of the current iteration
pm.info.iterationCount The total number of iterations that are scheduled to run
See the documentation: Scripting with request info
You want to execute "Request 6" at the very end, this means, when iteration and iterationCount are equal.
Note that iteration start at 0, so you need to add + 1 when comparing it to iterationCount.
Also, if this condition does not match, you need to set the nextRequest to null.
"Request 1" will be executed automatically by the Collection Runner. If you set the nextRequest to "Request 1", you will end up in an endless loop.
The following will do you what you want, you can put it as pre-request script or test of "Request 5".
if (pm.info.iterationCount == pm.info.iteration + 1) {
postman.setNextRequest("Request 6")
} else {
postman.setNextRequest(null)
}
I have an interactive grid with a custom button. The button, when clicked, processes the selected rows:
loops through all selected rows and executes a callback for each row if the row meets a criteria.
apex.server.process
("process_selected_callback"
,{x01:$my_id}
,{type:'GET', dataType: 'text', success: function( text) {}}
);
My callback contains basically this:
DECLARE
l_my_id NUMBER;
BEGIN
l_my_id := TO_NUMBER(apex_application.g_x01);
package1.my_process_record(l_my_id);
END;
Every loop iteration when a row criteria is met, before executing the callback, a page item is incremented to get the count of records processed.
At the end of the loop I call apex.submit:
apex.submit('DISPLAY_SUCCESS');
to call the process that grabs a page item containing count of records processed - P1_RECORDS_PROCESSED and uses apex_application.g_print_success_message to display a message to the user, stating how many records were processed.
Everything works fine but one issue - a lot of times DISPLAY_SUCCESS process gets executed before the callback and so the processed record count only gets incremented after the message is displayed. How can I ensure callback finishes before the page is submitted?
Perhaps there is a better way to process the selected rows?
One solution is to call the "show_message" functionality in the callback function.
apex.server.process
("process_selected_callback"
,{x01:$my_id}
,{type:'GET',
dataType: 'text',
success: function( text) {
apex.submit('DISPLAY_SUCCESS');
}
}
);
But the pitfall is that this will always submit the page when processing is done, regardless of any db errors that might occur. Since apex.server.process won't be triggered on DB errors, but just monitors whether the AJAX call has been succesfully executed.
To solve that issue, you can return a json object which holds the actual success result.
create or replace package1
procedure my_process_record
begin
apex_json.open_object;
<< place the processing logic here >>
apex_json.write('success', true);
apex_json.close_object;
exception
when others then
-- Free all output written so far
apex_json.free_output;
-- Create json error object
apex_json.open_object;
apex_json.write('success', false);
apex_json.write('result' , sqlerrm );
apex_json.close_object;
end;
end package1;
The ajax call could then act on the returned result tag
apex.server.process
("process_selected_callback"
,{x01:$my_id}
,{type:'GET',
dataType: 'json',
success: function( json) {
if ( json.hasOwnProperty("success") && json.success == true ) {
apex.submit('DISPLAY_SUCCESS');
}
else {
//Code to show the error
}
}
}
);
Hope this this and gives you a direction.
Two ways you can do this.
First Approach:
Use Javascript Promises. Apex makes it easy for you since apex.server.process returns a Promise object.
Since you are looping through the rows and executing the callback for each row, you can just store the returned Promise from each apex.server.process call into an array and then use Promise.all() function to wait for all of the Promises to be resolved (AJAX requests to be finished), and then call apex.submit('DISPLAY_SUCCESS');. If any one of your AJAX calls might fail, you can use Promise.allSettled() instead of Promise.all()
You can refer to this to understand the Promise.all() function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
Second Approach:
The first approach seems inefficient. Do you really need to make an individual AJAX call for each row processed because it seems that all you are doing is just passing an ID to a Package function?
Why not run a loop and store all the IDs in an array and then do JUST ONE AJAX call and pass the array to it? The looping through the IDs can be done by your AJAX PL/SQL code which will not only be faster (presumably) but also more efficient for the browser as it doesn't have to run through multiple AJAX calls and all the associated overhead.
I’m quite new to postman (and coding) and was trying to find and piece together many snippets of scripts to make it work the way I want.
What I want is very simple: I have a list of IDs that I want to make a POST in each of them, get one of the responseBody as a variable and do another POST. I think I’m close but I can’t manage to get it to work.
I’ve tried:
Two POST request in the same Collection and running the collection.
In the first request I have a POST to
https://APIADDRESS/?order_id{{orderid}}&contract[copy_order_data]=true
On the Pre-request Script tab:
var orderids = pm.environment.get(“orderids”);
if (!orderids) {
orderids = [“bc46bf79-2846-44ed-ac4d-78c77c92ccc8”,“81aacc33-1ade-41a3-b23e-06b03b526b8f”];
}
var currentOrderId = orderids.shift();
pm.environment.set(“orderid”, currentOrderId);
pm.environment.set(“orderids”, orderids);
On the Tests tab:
var orderids = pm.environment.get(“orderids”);
if (orderids && orderids.length > 0) {
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable(“invoice.id”, jsonData.invoice.id);
postman.setNextRequest(“Create invoice”);
} else {
postman.setNextRequest(null);
}
invoice.id is a environment variable populated with the response body of the first action/post and then using the variable on the second action/post.
And then the second request would be a POST to
https://APIADDRESS/invoices/{{invoice.id}}/finalize.json
Of course this doesn’t work. Either it doesn't run the second request in the collection or it doesn't do the loope to more than 1 ID on the list.
So I thought that putting the second POST inside the first one would solve it. But I had no luck.
Can please someone help me?
I have tried mentioned use case with sample API's provided by POSTMAN.
Can you try it?
First POST Method Request : https://postman-echo.com/post
Pre-request Script of first POST method
var orderids = pm.environment.get("orderids");
if(!orderids ){
orderids = ["bc46bf79-2846-44ed-ac4d-78c77c92ccc8","81aacc33-1ade-41a3-b23e-06b03b526b8f"];
}
var currentOrderId = orderids.shift();
pm.environment.set("orderid", currentOrderId);
pm.environment.set("orderids", orderids);
Tests Tab of first POST Method
var orderids = pm.environment.get("orderids");
if (orderids && orderids.length > 0) {
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("invoice.id", jsonData.headers.host);
postman.setNextRequest("Test1");
} else {
postman.setNextRequest(null);
}
Second POST Method Reqeust: https://postman-echo.com/post?key={{invoice.id}}
After executing the above collection it will set orederids and invoice.id value in environment variables and then it will call next POST Method.
Hope this will help you.
Thanks #HalfBloodPrince, from the Postman Echo it worked but in my case it doesn't :S
What I manage to get it working was using a Json file as a list of Orderids.
In that case I've separated all requests.
Request1 - https://APIADDRESS/?order_id{{orderid}}&contract[copy_order_data]=true
Tests tab:
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("invoice.id", jsonData.invoice.id);
Request2 - https://APIADDRESS/invoices/{{invoice.id}}/finalize.json
That way everything is in a neat and organized way.
Thanks
I've been researching A LOT for past 2 weeks and can't pinpoint the exact reason of my Meteor app returning results too slow.
Currently I have only a single collection in my Mongo database with around 2,00,000 documents. And to search I am using Meteor subscriptions on the basis of a given keyword. Here is my query:
db.collection.find({$or:[
{title:{$regex:".*java.*", $options:"i"}},
{company:{$regex:".*java.*", $options:"i"}}
]})
When I run above query in mongo shell, the results are returned instantly. But when I use it in Meteor client, the results take almost 40 seconds to return from server. Here is my meteor client code:
Template.testing.onCreated(function () {
var instance = this;
// initialize the reactive variables
instance.loaded = new ReactiveVar(0);
instance.limit = new ReactiveVar(20);
instance.autorun(function () {
// get the limit
var limit = instance.limit.get();
var keyword = Router.current().params.query.k;
var searchByLocation = Router.current().params.query.l;
var startDate = Session.get("startDate");
var endDate = Session.get("endDate");
// subscribe to the posts publication
var subscription = instance.subscribe('sub_testing', limit,keyword,searchByLocation,startDate,endDate);
// if subscription is ready, set limit to newLimit
$('#searchbutton').val('Searching');
if (subscription.ready()) {
$('#searchbutton').val('Search');
instance.loaded.set(limit);
} else {
console.log("> Subscription is not ready yet. \n\n");
}
});
instance.testing = function() {
return Collection.find({}, {sort:{id:-1},limit: instance.loaded.get()});
}
And here is my meteor server code:
Meteor.publish('sub_testing', function(limit,keyword,searchByLocation,startDate,endDate) {
Meteor._sleepForMs(200);
var pat = ".*" + keyword + ".*";
var pat2 = ".*" + searchByLocation + ".*";
return Jobstesting.find({$or:[{title:{$regex: pat, $options:"i"}}, { company:{$regex:pat,$options:"i"}},{ description:{$regex:pat,$options:"i"}},{location:{$regex:pat2,$options:"i"}},{country:{$regex:pat2,$options:"i"}}],$and:[{date_posted: { $gte : endDate, $lt: startDate }},{sort:{date_posted:-1},limit: limit,skip: limit});
});
One point I'd also like to mention here that I use "Load More" pagination and by default the limit parameter gets 20 records. On each "Load More" click, I increment the limit parameter by 20 so on first click it is 20, on second click 40 and so on...
Any help where I'm going wrong would be appreciated.
But when I use it in Meteor client, the results take almost 40 seconds to return from server.
You may be misunderstanding how Meteor is accessing your data.
Queries run on the client are processed on the client.
Meteor.publish - Makes data available on the server
Meteor.subscribe - Downloads that data from the server to the client.
Collection.find - Looks through the data on the client.
If you think the Meteor side is slow, you should time it server side (print time before/after) and file a bug.
If you're implementing a pager, you might try a meteor method instead, or
a pager package.
I have a big trouble with getting value from WS.url call.
val x =WS.url("https://www.google.com/recaptcha/api/siteverify?
secret=XX&response="+captcha).get().map {
response =>response.body}
When i try
Console.println("X: "+x)
I don't have expected value but:
X: scala.concurrent.impl.Promise$DefaultPromise#e17c7c
BUT, when i try to print value println(response.body) inside map function it works fine.
I also tried playframework tutorial but the same results.
So, how can I assign result of GET call into some variable?
Please don't assemble your own query string, use the withQueryString method.
There are two solutions to your problem: blocking and non-blocking. Blocking will mean that your request's thread will idle until the HTTP call completes. Non-blocking is preferred and you can provide Play with a Future to complete the request with. All you have to do is instead of Action use Action.async in your controller.
val captchaResponse: Future[String] =
WS.url("https://www.google.com/recaptcha/api/siteverify")
.withQueryString("secret" -> "XX", "response" -> "captcha")
.get()
.map(_.body)
// Non-blocking solution:
captchaResponse.map {
body =>
Console.println("X: " + body)
Ok(views.html.page(body.toBoolean))
}
// Blocking solution:
import scala.concurrent.duration._
val x = Await.result(captchaResponse, 3.seconds)
Console.println(x)