I'm trying to remove the value of a custom field on an asana task via a PUT request.
Based on the original json data I sent over to create the task with a custom field value and the documentation here this is my best guess for how this should look:
let data = {custom_fields: { ASANA_CUSTOM_FIELD_ID_NUMBER: null }}; //struggling here
updateTask(ASANA_TASK_ID_NUMBER, data);
function updateTask(id, data) {
return put(`https://app.asana.com/api/1.0/tasks/${ASANA_TASK_ID_NUMBER}`, data);
}
function put(url, data) {
return makeRequest({
"url": url,
"headers": {"Authorization": "Bearer " + accessCode()},
"type": "PUT",
"data": data
})
}
But I get the error:
status:400 Bad request
custom_fields: Value cannot be an array: []
Which seems verbose enough to solve except I've tried every format i can come up with and I've had no luck working it out. I know that the put function works fine for updating other fields for a task and I see the same error with an actual number other than null.
You will need to send your content in JSON rather than urlencoded data. This is a bit of a bug in Asana API in my opinion. They say that they support form-encoded content however it doesn't like it when you try to send an object as it thinks it's an array.
I'm not sure why, but setting custom fields seems to be different from the rest of the API requests.
Here is some code that works for setting it, you can probably figure out how to apply this to whatever language you're using:
function SetCustomField(taskId, fieldId, value) {
// not sure why, but to set the custom task you have to tell it your content type is json,
// then send json as a string instead of letting it serialize it for you
var headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer API-KEY'
};
var formData = '{"data": { "custom_fields": { "' + fieldId + '": ' + value + '} } }';
var options = {
'method': 'put',
'headers': headers,
'payload': formData
};
var response = UrlFetchApp.fetch('https://app.asana.com/api/1.0/tasks/' + taskId, options);
//Logger.log(response.getContentText());
}
Related
I have ajax connection with controller
function changeEmail() {
$.ajax({
...
contentType: "application/json",
dataType: "json",
...
error: function (error) {
var obj = error.responseText;
console.log('Error: ' + obj);
console.log('Obj length: ' + obj.fieldErrors.length);
}
});
}
Which in case of error returns a list of errors in json.
However, he is not able to refer to this list.
https://zapodaj.net/e6354b8c71f4c.png.html
I do not know, for example, how to refer to the first element of a list to the
message
variable
Depending on the content-type response from your server, the default response type is probably text/html or some other incorrect content-type.
You have two ways to fix this.
First, you can set obj = JSON.parse(error.responseText)
or, you can make sure that the server sets the correct content-type on errors as well.
I'm working on one project with AngularJs(1.5) and Codeigniter rest server. I'm wondering why data idTag isn't passed to php? Let me show you my code and explain further with comments.
I have this factory
factory.get = function(idLocation, idTag){
console.log(idLocation, idTag); //Console log outputs 1 6, so data is here
return $http({
method: 'GET',
url: $location.protocol() + '://' + $location.host() + '/rest/api/locationtag/locationtag/' + idLocation,
data: {
idTag: idTag
}
}).then(function successCallback(response){
console.log(response);
// response is empty, because data isn't sent to PHP
return response.data;
},function errorCallback(response){
console.log('Error getting slide shows: ' + response.data.message);
});
};
And this is my PHP where i try to fetch the code
public function locationtag_get($idLocation)
{
$condition['id_location'] = $idLocation;
$condition['id_tag'] = $this->get('idTag');
var_dump($condition);
die();
$locationTag = $this->locations_tags->get($condition);
if ($locationTag) {
$this->response($locationTag, REST_Controller::HTTP_OK);
}
}
Out put of var_dump is
'id_location' '1'
'id_tag' null
SO the question, why or how to properly send data from GET method to PHP rest controller in Codeigniter?
If you need any additional information's, please let me know and i will provide. Thank you in advance!
For GET requests you should use params instead of data (which is for POST requests). You can confirm this in the AngularJS documentation.
params – {Object.} – Map of strings or objects which
will be serialized with the paramSerializer and appended as GET
parameters.
Of course, nothing stops you from adding them to the URL but you'd have to deal with encoding the information properly instead of just passing the JSON object.
You should be using a params property in your $http config object:
$http({
url: $location.protocol() + '://' + $location.host() + '/rest/api/locationtag/locationtag/' + idLocation,
data: {,
method: "GET",
params: {idTag: idTag}
});
This will append as query string to you url, which you can then inspect in your server side code.
For my current project Java/Spring project I have to validate a form. The webpage is a freemarker template file.
The <form> has no special attribute to send the data to the controller. The project uses Ajax to send the request. The controller doesn't receive the form at all.
When the user submits the data, a JavaScript function is called to receive all the data by collecting the elementID's. The data is put in a variable, like this (short version);
var userId = document.getElementById('input_id').value.toLowerCase();
var width = document.getElementById("width");
var height = document.getElementById("height");
The function then puts all the data into a JSON. This JSON is put in the Ajax, and then Ajax calls the right controller.
**Ajax code **
$.ajax({
url: url,
type: "POST",
dataType: "json", // expected format for response
contentType: "application/json", // send as JSON
Accept: "text/plain; charset=utf-8",
"Content-Type": "text/plain; charset=utf-8",
data: data,
success: function (response) {
// we have the response
if (response.status == "SUCCESS") {
console.log("succes");
//Redirect to the right page if the user has been saved successfully
if (type === "setupuser") {
window.location = "/setup/user/" + userId;
} else if (type === "simulatoruser") {
window.location = "/simulator/user/" + userId;
}
} else {
errorInfo = "";
for (i = 0; i < response.result.length; i++) {
errorInfo += "<br>" + (i + 1) + ". " + response.result[i].code;
}
$('#error').html("Please correct following errors: " + errorInfo);
$('#info').hide('slow');
$('#error').show('slow');
}
},
error: function (e) {
alert('Error: ' + e);
}
});
The following controller is called by the Ajax request:
#RequestMapping(method = RequestMethod.POST, value = "/adduser/{userType}")
#ResponseBody
JsonResponse addUserMapping(#ModelAttribute(value="user") User user, BindingResult result, #RequestBody String jsonString, #PathVariable String userType) {
def json = new JsonSlurper().parseText(jsonString)
String userId = json.userId
String userName = json.userName
user.setId(userId)
user.setName(userName)
log.warn("User id..... "+user.getId())
log.warn("User name..... "+user.getName())
JsonResponse res = new JsonResponse();
ValidationUtils.rejectIfEmpty(result, "id", "userId can not be empty.");
ValidationUtils.rejectIfEmpty(result, "name", "userName can not be empty");
if(!result.hasErrors()){
userService.addUser(jsonString)
res.setStatus("SUCCESS");
}else{
res.setStatus("FAIL");
res.setResult(result.getAllErrors());
}
return res;
}
As you can see, Ajax sends a JSON to the controller. The controller unpacks the JSON and puts the data into the user object. Then the user object is being validated using "rejectIfEmpty()" method...
Now I've been reading about making a userValidator class extending Validator, or simply putting Annotations in the bean class like:
#Size(min=1, max=3)
I prefer these annotations since you don't have to write special code for checking certain simple things (like the field not being empty .. #NotEmpty)
But that doesn't work because the controller doesn't take a user object the second it's called, instead it takes the JSON and then unpacks it (Validating is too late..)
TL:DR
Controller takes a JSON as a parameter instead of an Object. The JSON has to be unpacked and then validated in the controller as a java object using rejectIfEmpty as an example. I don't want a full page reload, but I still want to keep Ajax.
BTW: I want to validate the data against more things like regex etc. But the rejectifEmpty is a simple example.
Does anyone have an idea how to handle this?
I fixed the validation by parsing the JSON in the controller and setting it in the user object. The user object is then put in my UserValidator class and validated.
Link for more info using the validator:
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/validation.html
I am trying to write some code that submits a ticket automatically with information from a page I created in Apps Script. I have tried numerous examples, but I can't seem to get my code to work.
var headers = {
'Content-type': 'application/json',
'Authorization': 'Basic ' + Utilities.base64Encode(API_KEY + ':X')
};
//Puts together the ticket according to the freshdesk api.
//var payload = '{"helpdesk_ticket":{"description":"' + message + '","subject":"' + subject + '","email":"' + arr[0][0] + '","priority":"' + ticketPriority + '","status":2}}';
//var payload = '{"helpdesk_ticket":{"description": message ,"subject": subject,"email": arr[0][0],"priority": ticketPriority,"status":2}}';
var payload = '{"helpdesk_ticket":{"description":"TEST","subject":"TEST","email":"test#test.com","priority":1,"status":2}}';
//Adds the extensions that are needed to post a new ticket to the end of the url
var url = ENDPOINT + '/helpdesk/tickets.json';
var options = {
'method': 'post',
'headers': headers,
'payload': payload,
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch(url, options);
This is what I currently have. I have gotten it to work once, but only when I do not have any variables being assigned to the 'description' or 'subject' header (the line with the payload variables that is uncommented. When I use that line, a ticket is successfully created). I am not sure why my first or second lines with the payload variables would not work. The variable 'message' is just a String with some new line characters '\n' in it. Does anyone know why this might be happening?
Solved by building the message variable with HTML code and using the 'description_html' property instead of 'description'.
I use $(document).ajaxSend(...) to dynamically add data (POST args) to some Ajax requests, when necessary.
Adding data works when some datas have been defined in an $.ajax(...) call. But if no data has been defined in the $.ajax setting, my $.ajaxSend can't add data to the settings.
Here is my $.ajaxSend interceptor:
$(document).ajaxSend(function(e, request, settings) {
if(settings.csrfIntention) {
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
}
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
else if(typeof(settings.data) == 'string') {
settings.data += '&_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
else if(!settings.data._token) {
settings.data._token = requestToken;
}
}
});
And an example of $.ajax call that works:
$.ajax({
url: opts.close.url,
method: 'POST',
data: { foo:'bar' },
csrfIntention: 'ajax_close_ticket',
success: function(data) { ... }
});
The $.ajaxSend works and settings.data is set to:
foo=bar&_token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%22uXV1AeZwm-bZL3KlYER-Dowzzd1QmCmaT6aJFjWLpLY%22%7D
Serverside, I can retrieve the two fields: foo and _token.
Now, if I remove the data object in the $.ajax call, the output of $.ajaxSend seems Ok, too:
_token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%225cK2WIegwI6u8K_FrxywuauWOo79xvhIcASQrZ9QPZQ%22%7D
Yet, the server don't receive my _token field :(
Another interesting fact: when I have the two fields, the Chromium dev tools under the Network tab displays the two fields under a "Form Data" title. When _token is alone, "Form Data" is replaced by "Request Payload".
Edit: just understood why _token is not interpreted by the server. If no data has been previously set in $.ajax call, jQuery does not add the right Content-Type in HTTP headers, it set it to text/plain instead of application/x-www-form-urlencoded. How can I force jQuery to add this header?
Edit 2: Solution found. Will post an answer to help other people...
I apologize for my bad English
I believe that the solution to his case would be the use of the function "ajaxSetup"
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
};
$.ajaxSetup({
data : {
_token: requestToken
}
});
this way all your orders took the data as the desire
A simpler approach:
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
}
var myForm = {};
myForm['_token'] = encodeURIComponent(JSON.stringify(requestToken));
In your ajax call:
myForm['foo'] = 'bar';
$.ajax({
url: opts.close.url,
method: 'POST',
data: myForm,
csrfIntention: 'ajax_close_ticket',
success: function(data) { ... }
});
//This sends foo and _token
Finally I answer my question after only 10 minutes...
In HTTP, the form arguments are sent into the request body, under the headers. The header Content-Type should be present to declare the data type. When this header is set to application/x-www-form-urlencoded, the server will understand that you sent a form and will parse the request body as a GET URL (you know, the foo=bar&key=val format).
jQuery adds this header automatically when you set a data object into the $.ajax call. Then it passes the request to the $.ajaxSend callback, which adds its proper fields.
When no data has been provided in request settings, jQuery do not add an unnecessary Content-Type: x-www-form-urlencoded in the request headers. Then, when you append the request body into your $.ajaxSend callback, jQuery do not check the data again and declares the content as text/plain. The server has nothing to do with text/plain so it does not interpret the body data as form fields.
You can obviously force jQuery to change the header to application/x-www-form-urlencoded, let's take the code of my original post :
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
Now add the right header:
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}