Invalid URL Error in alamofire in IOS while passing right url - get

What I want to do is to get json data from below url
https://query.yahooapis.com/v1/public/yql?q=select * from
weather.forecast where woeid in (select woeid from geo.places(1) where
text='seoul,kr') and u='c'&format=json
which works great if type it on browser.
but it dosen't work on alamofire...
I think it's because of ' mark
as I can see \ is embedded saying FATAL invalid url
let rrrr="https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='seoul,kr') and u='c'&format=json"
print(rrrr)
let alamo=Alamofire.request(rrrr,method:.get)
alamo.responseJSON {
response in
if response.data != nil {
print("not null")
let json = JSON(data: response.data!)
print(json)
print("not null21")
print(response)
print("not null12")
print(response.data!)
Log result is as follows
https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='seoul,kr') and u='c'&format=json
not null
null
not null21
FAILURE: invalidURL("https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\'seoul,kr\') and u=\'c\'&format=json")
not null12

As I have seen your URL string contains the spaces in select query.
Actually, alamofire doesn't support URL string with spaces. Try to replace the URL string spaces with %20 (i.e encoded character space).
OR you can use URL encoding with the Alamofire request.
Hope it will help!

I use this:
enum ConsultOfficesServiceEndpoints : String {
case getProposedPeople = "aaa/bbb/ccc/%d/"
}
.
.
.
func getProposedPeople(_ name: String, success: #escaping SuccessResponse,failure: #escaping FailureResponse){
var paramWithSpaces = ""
var lines = name.components(separatedBy: " ")
var numlines = lines.count
var i = 0
if numlines > 1{
while i < (numlines - 1) {
paramWithSpaces = paramWithSpaces + lines[i] + "%20"
i = i+1
}
paramWithSpaces = paramWithSpaces + lines[numlines - 1]
}else{
paramWithSpaces = name
}
self.GET(withEndpoint: ConsultOfficesServiceEndpoints.getProposedPeople.rawValue.replacingOccurrences(of: "%d", with: paramWithSpaces), params: nil, headers: nil, success: success, failure: failure)
}

Related

Node with SQL Server - response with for json path query not responding as expected

I am working with Node and SQL Server. Everything is fine with simple two dimensional tables, but when I try to do a nested query with a for json path response, I get an unexpected result I don't know how to solve with node.js
Here is my code:
let sqlString = `
SELECT codeid, code, validFrom, validTo,
(SELECT dbo.PLprospectAgentCodesComp.productIdentifier, dbo.masterGroupsProducts.productName, dbo.PLprospectAgentCodesComp.compensation
FROM dbo.PLprospectAgentCodesComp INNER JOIN
dbo.masterGroupsProducts ON dbo.PLprospectAgentCodesComp.productIdentifier = dbo.masterGroupsProducts.productIdentifier
WHERE (dbo.PLprospectAgentCodesComp.codeid = dbo.PLprospectAgentCodes.codeid) for json path ) as products
FROM dbo.PLprospectAgentCodes
WHERE (plid = ${userData.plid}) for json path`
let conn = await sql.connect(process.env.DB_CONNSTRING)
let recordset = await conn.query(sqlString)
if (recordset.rowsAffected[0] > 0) {
jsonResponse.success = 1
jsonResponse.data = recordset.recordset;
}
else {
JsonResponse.success = 0;
JsonResponse.message = "ERR 1:Invalid credentials";
}
res.json(jsonResponse)
await conn.close();
Everything was fine until I utilized for json auto at my sql string, which I need in order to get the results the way I need them.
I tried stringyfying, .toString(), JSON.parse, nothing worked, and this is the result I get:
{
"success": 1,
"data": [
{
"JSON_F52E2B61-18A1-11d1-B105-00805F49916B": "[{\"codeid\":1,\"code\":\"pablo\",\"validFrom\":\"2020-01-01\",\"validTo\":\"2022-01-01\",\"products\":[{\"productIdentifier\":\"Sigma\",\"productName\":\"Sigma Tramma\",\"compensation\":28.00},{\"productIdentifier\":\"membership\",\"productName\":\"Membership\",\"compensation\":30.00}]},{\"codeid\":2,\"code\":\"paola20\",\"validFrom\":\"2021-01-01\",\"validTo\":\"2020-01-01\",\"products\":[{\"productIdentifier\":\"Sigma\",\"productName\":\"Sigma Tramma\",\"compensation\":18.00},{\"productIdentifier\":\"membership\",\"productName\":\"Membership\",\"compensation\":20.00}]}]"
}
]
}
How can I fix this, from either the query, or Node?
Thanks.
As AlwaysLearning said, try
let sqlString = `
select (SELECT codeid, code, validFrom, validTo,
(SELECT dbo.PLprospectAgentCodesComp.productIdentifier, dbo.masterGroupsProducts.productName, dbo.PLprospectAgentCodesComp.compensation
FROM dbo.PLprospectAgentCodesComp INNER JOIN
dbo.masterGroupsProducts ON dbo.PLprospectAgentCodesComp.productIdentifier = dbo.masterGroupsProducts.productIdentifier
WHERE (dbo.PLprospectAgentCodesComp.codeid = dbo.PLprospectAgentCodes.codeid) for json path ) as products
FROM dbo.PLprospectAgentCodes
WHERE (plid = ${userData.plid}) for json path) as data`
This will result in
{
"success": 1,
"data": [
{
"data": "[{\"codeid\":1,\"code\":\"pablo\",\"validFrom\":\"2020-01-01\",\"validTo\":\"2022-01-01\",\"products\":[{\"productIdentifier\":\"Sigma\",\"productName\":\"Sigma Tramma\",\"compensation\":28.00},{\"productIdentifier\":\"membership\",\"productName\":\"Membership\",\"compensation\":30.00}]},{\"codeid\":2,\"code\":\"paola20\",\"validFrom\":\"2021-01-01\",\"validTo\":\"2020-01-01\",\"products\":[{\"productIdentifier\":\"Sigma\",\"productName\":\"Sigma Tramma\",\"compensation\":18.00},{\"productIdentifier\":\"membership\",\"productName\":\"Membership\",\"compensation\":20.00}]}]"
}
]
}
Then you can
let parsedResponse=JSON.parse(apiResponse.data[0].data);
console.log(parsedResponse)
Hope it helped.

how to escape ampersand in query payload in IDE

I have to add the following string to a restdb query:
&sort=_changed%26dir=-1
so it will look like this (which works in Postman):
{"identifier": "impeachmentsage"}&sort=_changed&dir=-1
I have tried several ways of escaping the &, including %26 and the ampersand character followed by amp; , but no matter what I get an error message complaining about the presence of the &. https://bixbydevelopers.com/dev/docs/reference/JavaScriptAPI/http#http-options
function getNewsByName(altBrainsNames, $vivContext) {
console.log('viv', $vivContext, altBrainsNames)
dashbot.logIncoming("Getting news by name", "GetNewsByName", $vivContext, altBrainsNames);
const url = properties.get("config", "baseUrl") + "content"
console.log("i got to restdb.js and the url is ", url);
console.log("AltBrainsNames is", altBrainsNames)
ampersand = "&"
const query = {
apikey: properties.get("secret", "apiKey"),
q: "{\"" + "identifier" + "\":\"" + altBrainsNames + "\"}" + ampersand+ "sort=_changed%26dir=-1"
}
console.log("query", query)
const options = {
format: "json",
query: query,
cacheTime: 0
}
Tried a couple of additional things.
var s = "sort=_changed%26dir=-1"
const query = {
apikey: properties.get("secret", "apiKey"),
q: "{\"" + "identifier" + "\":\"" + altBrainsNames + "\"}",
s: "sort=_changed%26dir=-1"
}
This gets closer and emits the ampersand, but the s= following it is extraneous.
UPDATE:
so I also tried constructing the complete URL and submitting it via the url parameter in getURL, bypassing the query option.
const url = properties.get("config", "baseUrl") + "content";
const q = "q={\"" + "identifier" + "\":\"" + altBrainsNames + "\"}";
const ampersand = encodeURIComponent("&");
submiturl = url + "\?" + q + ampersand + "sort=_changed" + ampersand + "dir=-1"
console.log('submit url is', submiturl)
const options = {
format: "json",
headers: {
'apikey': properties.get("secret", "apiKey"),
},
cacheTime: 0
}
console.log(options)
const response = http.getUrl(submiturl, options)
This produces a 400 error "unexpected & in JSON at column 32".
I now suspect that the fundamental problem is that getURL insists that the query string must be a matched key/value pair, while restdb's syntax provides for an unbalanced blank/value pair, i.e. &sort... rather than &s=sort. If this is the case, either getURL or restdb needs to change something...
Thanks so much to #rogerkibbe! Posting my final code here as there are one or two minor tweaks to get it in exactly the right format for restdb.
const url = properties.get("config", "baseUrl") + "content";
const q = "{\"" + "identifier" + "\":\"" + altBrainsNames + "\"}";
const options = {
format: "json",
headers: {
'apikey': properties.get("secret", "apiKey"),
},
query: {
q: q,
//identifier: "impeachmentsage",
sort: "_changed",
dir: -1,
//blank: "",
//withAmper: "hello&world"
},
cacheTime: 0
}
Your URL query parameters should just be a JSON object, "query" which is in the options object - Bixby will take care of all the escaping etc needed
For example:
let url = "https://postman-echo.com/get"
let options = {
format: 'json',
query: {
identifier: "impeachmentsage",
sorts: "_changed",
dir: -1,
blank: "",
withAmper: "hello&world"
}
};
let response = http.getUrl(url, options)
console.log ("response = " + JSON.stringify(response));
Results in the following URL being called
https://postman-echo.com/get?identifier=impeachmentsage&sorts=_changed&dir=-1&blank=&withAmper=hello%26world
I added "blank" as an example of passing an empty string/null and "withAmper" showing Bixby does any necessary escaping for you.
FYI - if you ever need to escape a URL, the build in Javascript encodeURI works well

Node JS: Add "/" on end of all url if there is not

How can i add "/" on end of all url if there is not on Node JS / Express ?
Thank you in advance
All you need to do is check whether the string last character is "/", and if its not add it.
like this:
var addSlash = function( str ) {
return str.substr(-1) !== "/" ? ( str + "/" ) : str
}
var url = require('url');
function addSlash = function (str) {
var u = url.parse(str);
if (u.pathname.substr(-1) !== "/") {
u.pathname += "/";
}
return url.format(u);
}
lastIndexOf return the last position where a slash is, and if it isn't at the end of the string, we add a slash to the url.
function addSlash(url) {
return url.lastIndexOf("/") == url.length - 1 ? url + "/" : url:
}
No modules required.

Get rid of these Optional values

Using Xcode 7 beta, Swift 2.0
I'm saving and loading credentials to keychain, somehow when loading I get "Optional(value)" back, it looks like this is really part of the string as it also displayed like so in a textbox or when sending to API
This is how I save and load credentials now, as you see I've done a lot of extra nil checking to make sure it is not nil or Optional, it is indeed a overuse of explanation marks...
func SaveCredentials(credentials : [String : String!]!) -> Bool
{
if(credentials.count == 2)
{
//only proceed when we have two keys: username and password
let username = credentials["username"]
let password = credentials["password"]
if let usernameStr = username
{//also tried username!=nil && password != nil
if let passwordStr = password
{ //usernameStr and passwordStr is of type String!
let NsDataUsername = usernameStr!.dataUsingEncoding(NSUTF8StringEncoding)
let NsDataPassword = passwordStr!.dataUsingEncoding(NSUTF8StringEncoding)
if(NsDataUsername != nil && NsDataPassword != nil)
{
LocalStorage.saveToKeyChain("username", data: NsDataUsername!)
LocalStorage.saveToKeyChain("password", data: NsDataPassword!)
return true
}
}
}
}
return false
}
func LoadCredentials() -> [String : String!]?
{
let NsDataUsername = LocalStorage.loadFromKeyChain("username")
let NsDataPassword = LocalStorage.loadFromKeyChain("password")
if(NsDataUsername != nil && NsDataPassword != nil)
{
let username : String! = String(NSString(data: NsDataUsername!, encoding: NSUTF8StringEncoding))
let password : String! = String(NSString(data: NsDataPassword!, encoding: NSUTF8StringEncoding))
if let usernameStr = username
{
if let passwordStr = password
{ // password is of type String!, passwordStr is of type String
var credentials : [String: String!] = [String : String]()
credentials["username"] = usernameStr
credentials["password"] = passwordStr
return credentials
}
}
}
return nil
}
And when I send to Api, this is my method that also requires a non-optional string. This method does work when logging in, getting strings from text fields, but does not filter out that Optional when coming from keychain.
func LoginUser(email : String!, password : String!)
{
print("LoginUser(email : \(email), password: \(password))")
var parameters = [String : AnyObject]()
parameters["UserName"] = email
parameters["Password"] = password
......
The strings that I send to the SaveCredentials method, are the same that the user logged in with:
func LoginLocalAccount(email : String!, password : String!)
{
databaseAPI.LoginUser(email!, password: password!) //login goes just fine
saveCredentials(email!, password: password!) //manages to get Optional in it..
}
I suspect it has something to do with saving and loading from keychain, for interests, this is what I use to save and load from keychain.
I want to get rid of them because when the app starts, it loads the credentials and tries to login at my API. Ofcourse I get an error back that the username is not a valid e-mail, because it is Optional(email#adress.com)
You're overusing !. You don't need them. Try to learn more about implicitly unwrapped optionals, optionals, ... Your code is a mess (no offense, everybody's learning).
Back to your optional problem, it's caused by this line:
let username : String! = String(NSString(data: NsDataUsername!, encoding: NSUTF8StringEncoding))
convenience init?(data: NSData, encoding: UInt) - inner part utilizes failable initializer, so, NSString? is the result. Then initialization of String with optional NSString? produces optional as well. But, it has no sense at all do it in this way.
First part - remove optional
Utilizing new guard:
guard let loadedPassword = NSString(data: passwordData, encoding: NSUTF8StringEncoding) else {
fatalError("Ooops")
}
loadedPassword contains NSString (not NSString?) now.
Second part - NSString -> String
You did probably read (if not, read) Strings and Characters about bridging, ... If you can freely exchange NSString with String, you can think that you're done:
var dict = [String:String]()
dict["password"] = loadedPassword
Nope. It produces following error:
NSString is not implicitly convertible to String; did you mean to
use 'as' to explicitly convert?
Slight change and now you're done:
var dict = [String:String]()
dict["password"] = loadedPassword as String
Complete example
let password = "Hallo"
guard let passwordData = password.dataUsingEncoding(NSUTF8StringEncoding) else {
fatalError("Ooops")
}
// save/load to/from keychain
guard let loadedPassword = NSString(data: passwordData, encoding: NSUTF8StringEncoding) else {
fatalError("Ooops")
}
var dict = [String:String]()
dict["password"] = loadedPassword as String
print(dict) // "[password: Hallo]\n"

Groovy - Check last character & if append on condition

This is an idomism question regarding groovy - what is the simplest way to check the last char of a String and if present not append it to a modified String?
For example in Java you could do some like this;
String url = "http://www.google.com"
//check to see if url already has / at the end
if (url.charAt(url.size()-1)=='/')
url =url + "Media"
else
url = "/Media"
​def url = 'http://test.com/'
url += url?.endsWith('/') ? 'Media' : '/Media'
//This should work as well but it would throw an
//ArrayIndexOutOfBoundException if url is empty ('')
//url += url[-1] == '/' ? 'Media' : '/Media'
println url​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

Resources