krl

How to tell if the result of pick() is a string


I'm using the Goodreads API through a datasource. I search with the ISBN number, and it returns results if it has any. Here's what it looks like if the book was found:

<GoodreadsResponse>
    <Request>
        <authentication>true</authentication>
        <key><![CDATA[--redacted--]]></key>
        <method><![CDATA[api_book_url]]></method>
    </Request>
    <book id="6558055">
        <title><![CDATA[Mythical Man-Month, The: Essays on Software Engineering, Anniversary Edition]]></title>
        <isbn><![CDATA[]]></isbn>
        <link>http://www.goodreads.com/book/show/6558055-mythical-man-month-the?utm_medium=api&amp;utm_source=book_link</link>
    </book>
</GoodreadsResponse>

If the book wasn't found, it will be the same except that the <book> section is absent. You can imagine what the JSON looks like once this XML has been parsed by KRL.

I'm pick()ing the link tag out of the response like this:

url = data.pick("$..link.$t");

If there is a <book> section, that works just fine; url will be a string. But if there was not a <book> section, url will be an empty array ([]).

I only want the actions in my rule to run if url is a string. I've tried using things like if url != [] then or url.length() (which is always zero), but none of those work.

How can I tell when url is a string and when it is an empty array?


Solution

  • The direct answer to your question is .typeof(), docs here.

    Example condition and action:

    if url.typeof() eq 'array' then  
      noop()
    

    Another way to handle this situation is to pass in true as the second argument of pick, which will cause the answer to always be an array. This is described in the docs of pick.

    Since it will always be an array, you can use .length() to test for a match.