Search code examples
bixbybixbystudio

how to escape ampersand in query payload in IDE


error message

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.

enter image description here

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...

url constructed


Solution

  • 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