Alamofire Swift 2.0 <unknown>:0: error: tuple pattern cannot match values of the non-tuple type 'Response<String, NSError>' - alamofire

I am using Manger class for request. When I compile it shows
<unknown>:0: error: tuple pattern cannot match values of the non-tuple type 'Response<String, NSError>' Error`.
Its working fine in old Swift Xcode 6.*. But in Xcode 7.* its not working.
let aManager = Manager.sharedInstance
aManager.request(.GET, URLStrings.BASE_URL + URLStrings.CATEGORIES)
.responseString { _, _, result in
print("Response String: \(result.value)")
}
.responseJSON { _, _, result in
print("Response JSON: \(result.value)")
}
On clicking responseString it shows ?
Kindly Help me.

I supposed that you are using the 3.0+ Alamofire.
I encounter this problem recently, here is my solution:
for you code replace _, _, result to response and query the response data by response.data or response.result.value
For more information about the new response structure, you can check the official document here: enter link description here
Hope these helps.

You're on the Alamofire 3.0.0-beta.1 pre-release. You should switch back to Alamofire 2.0.2 (the latest release) until we have all the documentation and migration guides up-to-date.

I change my code in to this form. Now What I have to do is Convert data to JSon Object my self. But its working now for me.
let aManager = Manager.sharedInstance
aManager.request(.GET, URLStrings.BASE_URL + URLStrings.CATEGORIES )
.response {
(request, response, data, error) in
if let response = response {
print("GET REQUEST: \(request?.description)")
print("GET REQUEST: \(response.statusCode)")
if response.statusCode == 200 || response.statusCode == 201 {
}
}
else {
}
}

I check the official document here: Response Serializers
In the document, find Response Serializers, read the example code, I post it in here:
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
debugPrint(response) // prints detailed description of all response properties
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
Hope it can helps you~

Related

Karate.prevRequest.body is giving null value

Hi Karate community wish you can help me with this doubt ,I'm trying to create some evidence for my test cases ,because the organization where I'm working is not accepting neither cucumber or karate report.
The problem happen when my javaScript function use the karate.prevRequest.body functionality of karate, this brings a null value, but I already try it at feature level and work perfectly, I really don't know what's going on, I hope someone know what I'm doing wrong.
Here the piece of code and responses I'm getting from the feature and from the javaScript.
from Feature
* def requestBody = karate.prevRequest.body
* def requestString = new java.lang.String(requestBody, 'utf-8')
* print requestString
Response
11:09:15.800 [ForkJoinPool-1-worker-3] INFO com.intuit.karate - [print] {"enrollmentTimeStamp":"2021-03-26T11:09:14","customer":{"customer":"2021032611306","fullName":"Elizabeth Chase Olsen"}}
javaScript under the same feature
And configure afterScenario =
"""
function() {
if( karate.prevRequest != null){
var requestBody = new java.lang.String( karate.prevRequest.body , 'utf-8');
}
var requestMethod = karate.prevRequest.method;
var requestHeaders = karate.prevRequest.headers;
var request = requestMethod + "\n" +requestHeaders+ requestBody;
karate.log(requestBody);
var reportResults = Java.type('Features.reportResults').writeResultsToFilePretty(requestMethod, requestHeaders, requestBody, response, karate.info.scenarioName, karate.info.featureFileName);
}
"""
Response:
11:09:16.040 [ForkJoinPool-1-worker-3] ERROR com.intuit.karate - javascript function call failed: java.lang.NullPointerException
11:09:16.043 [ForkJoinPool-1-worker-3] ERROR com.intuit.karate - failed function body: function() {
if( karate.prevRequest != null){
var requestBody = new java.lang.String( karate.prevRequest.body , 'utf-8');
}
var requestMethod = karate.prevRequest.method;
var requestHeaders = karate.prevRequest.headers;
var request = requestMethod + "\n" +requestHeaders+ requestBody;
karate.log(requestBody);
var reportResults = Java.type('Features.reportResults').writeResultsToFilePretty(requestMethod, requestHeaders, requestBody, response, karate.info.scenarioName, karate.info.featureFileName);
}
11:09:16.044 [ForkJoinPool-1-worker-3] WARN com.intuit.karate - afterScenario hook failed: javascript function call failed: java.lang.NullPointerException
First please switch to 1.0 - it is quite likely this is fixed or work better: https://github.com/intuit/karate/wiki/1.0-upgrade-guide
Second: if you want custom reports and are willing to do some digging into Java code, see this: https://stackoverflow.com/a/66773839/143475
Third, maybe this will give you the "evidence" your organization is demanding, but again, you should be willing to do some custom code: https://twitter.com/KarateDSL/status/1338892932691070976
Fourthly, there is something called a RuntimeHook for advanced users, so if you understand how to use that - you can get the details of every single HTTP request made by Karate.
Finally, if none of the above work that means you should contribute some code to Karate :)

Google Apps Script/URLFetchApp and using returned data

I am very new to this, so please bear with me-- I have currently have an operational google apps script on the backend of a google sheet that is generated from Google Form answers. I am essentially setting up a ticket form in google forms that will trigger the data in the corresponding sheet to be sent via api call to our ticketing system. It works great, but I am trying to optimize it currently. The goal is to take the json response I get using:
Logger.log(response.getContentText());
which provides me the following info:
Aug 9, 2020, 11:44:40 AM Info {"_url":"https://testticketingsystem.com/REST/2.0/ticket/123456","type":"ticket","id":"123456"}
and send another API call to send data to that new ticket.
Here's a code snippet:
var payload = {
"Subject": String(su),
"Content": String(as),
"Requestor": String(em),
"Queue": String(qu),
"CustomFields": {"CustomField1": String(vn), "CustomField2": String(vb), "CustomField3":
String(vg), "CustomField4": String(av), "CustomField5": String(ov), "CustomField6":
String(sd)}
}
var options = {
'method': 'post',
"contentType" : "application/json",
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
}
var url = "https://testticketingsystem.com/REST/2.0/ticket?token=****************";
var response = UrlFetchApp.fetch(url,options);
Logger.log(response.getContentText());
} catch (error) {
Logger.log(error.toString());
}
}
After the ticket is created, how do I script the use of that ID number as a variable into my next api call?
Thank you!
UrlFetchApp.fetch returns a HTTPResponse, and if you expect JSON then you should be able to just use JSON.parse() to create an object from the text. (The JSON object is a standard JavaScript global object like Math; it is not Google Apps Script specific.)
If all goes well, you should just be able to use
var response = UrlFetchApp.fetch(url,options);
var data = JSON.parse(response.getContentText());
var id = data.id;
and then use that id for your next fetch().
Notes
If your literal response is indeed
Aug 9, 2020, 11:44:40 AM Info {"_url":"https://testticketingsystem.com/REST/2.0/ticket/123456","type":"ticket","id":"123456"}
you will run into trouble as everything until the { is invalid JSON (use a linter if you need to check yourself). But I'm assuming that was added by the console when you logged JSON, and not in the actual response itself.
JSON.parse() throws an error with invalid JSON, so you can use try/catch if needed.
You can also check the headers before you try to JSON.parse().
Here's an example that checks and handles issues, should they arise.
var type = response.getHeaders()["Content-Type"];
var text = response.getContentText();
if (type === "application/json") {
try {
var data = JSON.parse(text);
} catch (error) {
return Logger.log("Invalid JSON: " + response.getContentText(text));
}
} else {
return Logger.log("expected JSON, but got response of type: " + type);
}
// if we get to this line, data is an object we can use

Need my server to return a response that includes a data error. Need client to see what was wrong with data in request

As it will become quickly apparent, I have never seriously written a webserver before
Here is the current scenario:
Clients make requests to webserver, asking to save some data
Server looks at payload, and makes 2 checks
a. Is this client banned from saving data?
b. Does the payload of this data pass a language filter?
Server responds with success, or one of those 2 errors
My endpoint is written with Express in TypeScript
class ChatRequest {
public uid: string;
public message: string;
}
export const register = (app: express.Application, deps: dependencies.IDependencies) => {
app.post("/sendChat", (req: express.Request, res: express.Response) => {
transformAndValidate(ChatRequest, req.body)
.then((sendGlobalChatRequest: SendGlobalChatRequest) => {
const payload = {
message: sendGlobalChatRequest.message,
uid: sendGlobalChatRequest.uid
};
//Check if uid is banned here
//Check if payload passes language filter here
//Save Payload here
res.sendStatus(200);
}, (err) => {
deps.logger.error(err);
res.sendStatus(503);
});
});
I have been using this article for reference:
https://hackernoon.com/the-request-sent-bad-data-whats-the-response-94088bd290a
But I think my conclusion is that they are discussing something slightly different.
So from my understanding, I can just make up HTTP codes...
so I could just do res.sendStatus(499); if the uid is banned, and maybe res.sendStatus(498); if the payload doesn't pass language filter
Then my client can just read the Int statusCode and quickly determine the failure.
But even though I think I can do that, and it would work, it doesn't seem right?
Should I instead be using a standard HTTP Response Code? https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
And then add in the body of the response, a String or something that my client can parse to determine the error?
The String parsing seems way harder to maintain, but technically seems more "legal" if that makes sense?
What is the best way for me to have a client determine the type of server-side error?
I decided to return 400 with a JSON mapping errors to bools
if (isProfane(message)) {
res.status(400).json({messageContentBlocked: true});
}
In this way the client can receive multiple errors for the request at once, and it's more explicit
And in case anyone is googling around, I am using RxSwift/RxCocoa
Here is how I handle the error on the client:
extension Error {
var chatMessageBlockedURLError: Bool {
guard let rxCocoaURLError = self as? RxCocoaURLError else {return false}
switch rxCocoaURLError {
case let .httpRequestFailed(response, data):
guard response.statusCode == 400, let data = data else {return false}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
guard let errors = try? decoder.decode([String:Bool].self, from: data) else {return false}
return errors["messageContentBlocked"] == true
default:
return false
}
}
}

How to upload file in jhipster form?

I am just starting to use jhipster 5 and angular 5. I have a form and in that form in addition to few regular fields, I have a file input.
I could not find any documentation on how to file in jhipster.
EDIT 1:
I could somehow managed to upload file and send to server. Below is my server method to handle the form submission.
#PostMapping("/email-jobs")
#Timed
public ResponseEntity<EmailJobDTO> createEmailJob(MultipartFile file, #Valid #RequestBody EmailJobDTO emailJobDTO) throws URISyntaxException {
log.debug("REST request to save EmailJob : {}", emailJobDTO);
if (emailJobDTO.getId() != null) {
throw new BadRequestAlertException("A new emailJob cannot already have an ID", ENTITY_NAME, "idexists");
}
System.out.println(file.getName() + " File Name ");
EmailJobDTO result = emailJobService.save(emailJobDTO);
return ResponseEntity.created(new URI("/api/email-jobs/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
.body(result);
}
Here i get following exception,
Unsupported Media Type: Content type 'multipart/form-data;boundary=----WebKitFormBoundary73sdwuJtdeRk6xsO;charset=UTF-8' not supported
If I remove #RequestBody from method signature then I dont get above exception but then I start getting 400 bad request exception saying my form fields can not be null.
You must define MultipartFile is #RequestParam and declare produces = MediaType.APPLICATION_JSON_VALUE in post mapping, like:
#PostMapping("/email-jobs", produces = MediaType.APPLICATION_JSON_VALUE)
Client side, you can try send request as this:
Upload.upload({
url: 'api/path',
data: {
file: yourdatafile
},
headers: {'Content-Type': 'multipart/form-data'}
}).progress(function (evt) {
// handle progress
}).success(function (data, status, headers, config) {
// handle success
});
Instead of uploading a file, create a field type as a BLOB and then in your business logic, make a file if u need or else do your.

Alamofire returning status Failure Always

I am using Alamofire in my App. This is my Alamofire request code
let params: [String:AnyObject] = ["email": self.signin_Email.text!, "password": self.signin_Password.text!]
Alamofire.request(.GET, "http://DomainName/api/App/Sign_Up", parameters: params, encoding:.JSON)
.responseJSON { response in
debugPrint(response)
}
when i put debugPrint(reponse)
what i got is this
[Request]: { URL:
http://Domain/api/App/Sign_Up } [Response]: nil [Data]:
0 bytes [Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-1017
"cannot parse response" UserInfo={NSUnderlyingError=0x7ffe0840e700
{Error Domain=kCFErrorDomainCFNetwork Code=-1017 "(null)"
UserInfo={_kCFStreamErrorCodeKey=-1, _kCFStreamErrorDomainKey=4}},
NSErrorFailingURLStringKey=http://Domain/api/App/Sign_Up,
NSErrorFailingURLKey=http://Domain/api/App/Sign_Up,
_kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-1, NSLocalizedDescription=cannot parse response}
Here i am always getting the response status as Failure. I am not able to figure out what's going on. (using mvc4 as backend).
This is the Api method that accepts the above given request and returns a JSON Data
[System.Web.Http.HttpGet]
public JsonResult Sign_Up(string email,string password)
{
email = email;
password = password;
System.Web.Mvc.JsonResult usertoreturn = new System.Web.Mvc.JsonResult();
SignUpViewModel signupviewmodel = new SignUpViewModel();
usermodeltocheck.SetPassword(password);
usermodeltocheck.MembershipDate = DateTime.Now;
usermodeltocheck.IsMember = true;
usermodeltocheck.PublicKey = Guid.NewGuid().ToString("N");
usermodeltocheck.MembershipStatus = true;
usertoreturn.Data = Helper.UpdateUser(usermodeltocheck);
}
usertoreturn.JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet;
return usertoreturn;
}
UPDATE #1 I have created a new method named test that accepts a parameter.The method just returns the parameter value .I tried the sample code available in Github and its working. I am able to get proper response if I am avoiding parameters argument in Alamofire request Method. like
Alamofire.request(.GET, "http://DomainName/api/App/Test", encoding: .JSON).responseJSON{
response in
debugPrint(response)
}
here I am getting a SUCCESS response. I have updated my code like this
Alamofire.request(.GET, "http://DomianName/api/App/Test?test=testing", encoding: .JSON).responseJSON{
response in
debugPrint(response)
}
here also I am getting SUCCESS response. The Error occurs when I pass parameter value to the argument parameters parameters: ["test":"testing"].
also I set my parameters like this
let params = ["test":"testing"]
Alamofire.request(.GET, "http://DomianName/api/App/Test", parameters : params ,encoding: .JSON).responseJSON{
response in
debugPrint(response)
}
in this way also i am getting my response to FAILURE
May be its not an answer you are looking for but for me removing a parameter from Alamofire request method did the trick. Here is the change:
let params : [String:AnyObject] = ["email":self.signin_Email.text!,"password":self.signin_Password.text!]
let request = Alamofire.request(.GET, "http://DomianName/api/App/Sign_Up", parameters: params).responseJSON{
response in
switch response.result{
case .Success(let data) :
let json = JSON(data)
print(json)
case .Failure(let error):
print("Error : \(error)" )
}
}
I have removed encoding:.JSON from my Alamofire request method parameter list and that's it...
Try to print out all the data in response using the following:
let URLString = "http://DomainName/api/App/Sign_Up"
Alamofire.request(.GET, URLString, parameters: params, encoding:.JSON)
.responseJSON { response in
debugPrint(response)
}
Once you print it out, if you could update your question, we could help further. I'll update my answer accordingly afterwards. 👍🏼
Update #1
Okay, so the NSURLErrorDomain Code=-1017 points out that your server is most likely misbehaving. Are you able to successfully use cURL, Postman, Paw or some other HTTP client to hit the service? Once you get one of those working, you should use debugPrint on the `request object to compare.
let URLString = "http://DomainName/api/App/Sign_Up"
let request = Alamofire.request(.GET, URLString, parameters: params, encoding:.JSON)
.responseJSON { response in
debugPrint(response)
}
debugPrint(request)
This will show you the cURL command for the request.
I know this is kind of old but I stumbled upon this looking for something else. From what I have seen, I tend to get errors in this situation any time params are passed as JSON encoded with a .GET instead of a .POST
Changing the server to take a post for the URI makes everything flow correctly, and I guess in theory that is correct behavior, since if you aren't passing the values in the URL, you are technically posting the JSON to the endpoint.