I am writing a program in nodejs using the request-promise-native module to create a startup script,receive the script ID then create a server and apply the script ID, however even after gathering the script ID and passing it to the request to create the server it does not get applied. I have made sure that the value of the variable I am passing for the scriptID is in the correct form of data type but it still seems not to work for some reason
var scriptRequest = require('request-promise-native');
var serverRequest = require('request-promise-native');
var headers = {
'API-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
};
var scriptOptions = {
url: "https://api.vultr.com/v1/startupscript/create",
method: "POST",
headers: headers,
form: {
name: "test script",
script: "#!/bin/bash \napt-get update (not the actual script, just shortened it since the script itself is long and as of now the vultr server doesn't even make it this far)"}
};
var serverOptions = {
url: 'https://api.vultr.com/v1/server/create',
method: 'POST',
headers: headers,
form: {
DCID: '6',
VPSPLANID: '202',
OSID: '215',
SCRIPTID: scriptResponse
}
};
var scriptResponse;
async function main(){
const response = await scriptRequest({...scriptOptions, json:true})
const json = response.SCRIPTID
scriptResponse = json
await serverRequest(serverOptions)
}
main()
as you can see I have had to make the scriptRequest variable global, if I try to set it in the main function it gives me an undefined error in the serverOptions block
EDIT: just to clarify, the script ID I want to apply to the scriptResponse variable is returned upon making the scriptRequest post request
Related
So I am using query strings to pass data from a form to my server. The query strings look like this:
this.$http.post('http://localhost:3000/operation?Stime='+this.Stime+'&Etime='+this.Etime+'&eAMPM='+this.eAMPM+'&sAMPM='+this.sAMPM+'&id='+this.id+'&activity='+this.activity+'&auto_insert='+this.auto_insert+'&yearmonthday='+this.yearmonthday+'&color1='+this.c)
and In my server I have all these variables to store the query's variables:
var color = req.query.color1;
var Stime = req.query.Stime;
var Etime = req.query.Etime;
var sAMPM = req.query.sAMPM;
var eAMPM = req.query.eAMPM;
var id = req.query.id;
var activity = req.query.activity;
var requestAccepted = req.query.requestAccepted;
var yearmonthday = req.query.yearmonthday;
var auto_insert = req.query.auto_insert;
It just seems like a lot of code to just post my variables to the server (It works just fine) but I was wondering if there were some ways I could refactor it/ make it cleaner
Of course there is!
Consider doing some research into the HTTP message body:
A message body is the one which carries the actual HTTP request data (including form data and uploaded, etc.) and HTTP response data from the server ( including files, images, etc.).
In your case, you can change your Angular $http POST request to as follows -
var data = {
Stime: '+this.Stime+',
Etime: '+this.Etime+',
eAMPM: '+this.eAMPM+',
sAMPM: '+this.sAMPM+',
id: '+this.id+',
activity: '+this.activity+',
auto_insert: '+this.auto_insert+',
yearmonthday: '+this.yearmonthday+',
color1: '+this.c+'
}
$http({
method: 'POST',
url: 'http://localhost:3000/operation',
data: JSON.stringify(data)
})
I've been trying to develop some api controller in ASP.NET that comunicates with mongoDB. In same controller I have few post/get methods, and they are working just fine. When I want to update collection in mongoDB, i call post method and when debbuging, all fields in that method are filled, but in return i get 500 error. Any idea where is the problem? The code that I use is:
JavaScript
comment.id += id;
comment.comment += test;
var newCommentUrl = 'api/PostInfo/' + comment;
postDataToDatabase(comment, newCommentUrl);
function postDataToDatabase(data, url) {
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
url: url,
type: 'POST',
contentType: 'application/json;',
data: JSON.stringify(data),
success: function (valid) {
if (valid) {
} else {
}
}
});
ASP.NET Controller Method
[HttpPost]
[Route("api/PostInfo/{Comment}")]
public async void Post(Comment comment)
{
BsonObjectId oldId = new BsonObjectId(new ObjectId(comment.id.ToString()));
var mongoDbClient = new MongoClient("mongodb://127.0.0.1:27017");
var mongoDbServer = mongoDbClient.GetDatabase("nmbp");
var collection = mongoDbServer.GetCollection<PostInfo>("post");
var filter = Builders<PostInfo>.Filter.Eq(e => e._id, oldId);
var update = Builders<PostInfo>.Update.Push("post_comments", comment.comment);
await collection.FindOneAndUpdateAsync(filter, update);
}
It looks like method is called, but for some reason it returns 500.
If you are using async await pattern in your code, you must always as a best practice return a Task object when the method returns a void i.e. does not return any object.
In your situation, you need to use the following action method that is returning a Task object rather than the original one in which a void was being returned.
[HttpPost]
[Route("api/PostInfo/{Comment}")]
public async Task Post(Comment comment)
{
BsonObjectId oldId = new BsonObjectId(new ObjectId(comment.id.ToString()));
var mongoDbClient = new MongoClient("mongodb://127.0.0.1:27017");
var mongoDbServer = mongoDbClient.GetDatabase("nmbp");
var collection = mongoDbServer.GetCollection<PostInfo>("post");
var filter = Builders<PostInfo>.Filter.Eq(e => e._id, oldId);
var update = Builders<PostInfo>.Update.Push("post_comments", comment.comment);
await collection.FindOneAndUpdateAsync(filter, update);
}
This is according to Microsoft documentation at this URL: Async Await Best Practice
In the following example, async method Task_MethodAsync doesn't contain a return statement. Therefore, you specify a return type of Task for the method, which enables Task_MethodAsync to be awaited. The definition of the Task type doesn't include a Result property to store a return value.
A code sample from above documentation illustrating this best practice is as given below.
// TASK EXAMPLE
async Task Task_MethodAsync()
{
// The body of an async method is expected to contain an awaited
// asynchronous call.
// Task.Delay is a placeholder for actual work.
await Task.Delay(2000);
// Task.Delay delays the following line by two seconds.
textBox1.Text += String.Format("\r\nSorry for the delay. . . .\r\n");
// This method has no return statement, so its return type is Task.
}
I am developing a Google App Script to determine the size of a remote resource without downloading it. The code is as follows
function getRemoteFileSize()
{
var params = { "method" : "head" };
var resp = UrlFetchApp.fetch("https://www.google.com/images/srpr/logo11w.png", params);
Logger.log("Remote File Size: " + resp.getAllHeaders()["Content-Length"]);
}
However, Google App Script does not seem to support head requests and the code above cannot be executed.
What can be a viable alternative other than issuing a GET request ?
I am open to all suggestions including usage of a third-party service which has an API
You can try to override the method by setting the "headers" advanced parameter:
var params = {"method" : "GET", "headers": {"X-HTTP-Method-Override": "HEAD"}};
I've never used "HEAD", so I can't tell you for sure that this will work, but I have used the method override for "PATCH", and had that work.
I found that for my circumstance, I was able to use the Range header to request 0 bytes and then inspect the response headers which held the file size:
var params = {
method: "GET",
headers: {
Range: "bytes=0-0",
},
};
var response = UrlFetchApp.fetch(fileUrl,params);
var headers = response.getHeaders();
var fileSizeString = headers['Content-Range']
var fileSize = +headers['Content-Range'].split("/")[1];
The response headers had Content-Range=bytes 0-0/139046553 as a value that I could then use to convert to an integer (139046553) number of bytes.
I have a function below (searchTerm) which is supposed to fetch data from two URL's simultaneously and display the result after both the calls are completed.
This is working fine when I call with only one parameter in .when (say $.ajax(options1)),
but as I need the output from both in parallel, I am calling both URL's and recording responses data1 and data2 in .then function, but now it is not getting called after the ajax calls are completed.
Can anyone tell if I am correct in this approach? If so, then why is the callback not getting executed?
var searchTerm = function() {
var $a = $(this);
var term = $("#searchbox").val();
var options1 = {
url: "someurl1",
contentType: "application/json",
data: JSON.stringify({
searchString: term
}),
type: "post",
dataType: "html"
};
var options2 = {
url: "someurl2",
contentType: "application/json",
data: JSON.stringify({
searchString: term
}),
type: "post",
dataType: "html"
};
$.when($.ajax(options1), $.ajax(options2)).then(function(data1, data2) {
alert("callbacks finished");
});
Info1:
It seems any ajax call I specify as first argument is failing with 500 server error. I tried swapping options1 and options2, and now the call with options2 fails.
Info2:
The url that I have mentioned as part of options1 and options2 point to action methods in the same controller and they both return awaitable Task of (ActionResult) object. Can this be the problem here? Are the calls somehow blocking/interrupting each other over async requests?
Info 3:
Trying to provide more details to work with. The definition of the action methods are like this -
public async Task<ActionResult> someurl1(.....){
...
...
return await View(...);
}
Finally, I found the answer after debugging through all the subsequent calls. I was calling a common function from both action methods which uses a global variable to make external URL calls. Simply used the below locking mechanism to make my critical section thread-safe.
public static object Lock = new object();
lock (Lock) // added for thread safety purpose
{
response_task = CallExtern(...)
}
Try adding the option
async: false
to the ajax objects.
Inside my MVC view I have javascript that is executed by a button click. I'm trying to set a string to a random set of characters which I can get to work fine but when I try and set that string to 'randomchars' string inside the javascript I get a NullReferenceException when I try and run the view.
Below is the code snippet, the CreateRString is where the model parameter (RString) is set to the random string.
<script type="text/javascript">
function showAndroidToast(toast) {
var url = '#Url.Action("CreateRString", "Functions")';
$.ajax({ url: url, success: function (response) { window.location.href = response.Url; }, type: 'POST', dataType: 'json' });
var randomchars = '#(Model.RString)';
}
</script>
Is the syntax correct? I'm not too sure why it's getting the NULL.
The javascript is executed after the page been delivered to the client (i.e. web browser). Your razor code here is executed on the server before the page is sent to the client. Therefore, the ajax method will execute after you try to access Model.RString
To fix this you can either call CreateRString on the server, or you can set randomchars by using the response in the success callback.
To explain option 2 a bit further. You could do something like this:
//Action Method that returns data which includes your random chars
public JsonResult CreateRString()
{
var myRandomChars = "ABCDEF";
return new JsonResult() { Data = new { RandomChars = myRandomChars } };
}
//The ajax request will receive json created in the CreateRString method which
//contains the RandomChars
$.ajax({ url: url, success: function (response) {
var randomchars = response.Data.RandomChars;
window.location.href = response.Url;
}, type: 'POST', dataType: 'json' });
More specifically, the razor calls #Url.Action("CreateRString", "Functions") and #(Model.RString) execute first on the server.
Then showAndroidToast executes in the client's browser when you call it.