Error Object doesn't support this property or method: 'j.url'

Not a coder, but a tinkerer and learning. Would appriciate any help.
I have this script working with another simmilar API, but I am getting this error both with Cat & Dog API
"‘Object doesn’t support this property or method: ‘j.url’’ v )"

I have a API key, but as the URL works without the API Key, I am trying without it, would appriciate if someone can show me how to use the API key in the below script.

My Script


Sub Cat_OnLoad
Dim http,aURL
aURL = “https://api.thecatapi.com/v1/images/search
Set http = CreateObject(“Msxml2.XMLHTTP”)

http.open "GET",aURL,False
http.send
strJson = http.responseText

EKOManager.StatusMessage ("the URL to get is" & strJson)

Set j = ParseJson(strJson)
Result = j.url

EKOManager.StatusMessage ("the URL for the image  is " & Result)

End Sub

Function ParseJson(strJson)
Set html = CreateObject(“htmlfile”)
Set window = html.parentWindow
window.execScript "var json = " & strJson, “JScript”
Set ParseJson = window.json
End Function

when I run the url “https://api.thecatapi.com/v1/images/search” thru this JSON checker https://jsonformatter.curiousconcept.com/ it says there is an [Invalid encoding, expecting UTF-8] Could that be the reson for my issues?

Any suggestions please?

Can you show us what you’re getting when you access that URL directly, by pasting here what you pasted into the JSON formatter?

It definitely seems like you’re not getting proper JSON, which is why j.url is not defined.

9 out of 10 times, I get a response simmilar to this in the browser
[{“breeds”:[],“id”:“MTY4NDM4Mg”,“url”:“https://cdn2.thecatapi.com/images/MTY4NDM4Mg.jpg",“width”:500,"height”:331}]

and the remaining 10% of the time, (I just refresh the page multiple times) and I get a more qualified response like this.
[{“breeds”:[{“weight”:{“imperial”:“5 - 10”,“metric”:“2 - 5”},“id”:“orie”,“name”:“Oriental”,“cfa_url”:“http://cfa.org/Breeds/BreedsKthruR/Oriental.aspx",“vetstreet_url”:“http://www.vetstreet.com/cats/oriental”,“vcahospitals_url”:“https://vcahospitals.com/know-your-pet/cat-breeds/oriental”,“temperament”:"Energetic, Affectionate, Intelligent, Social, Playful, Curious”,“origin”:“United States”,“country_codes”:“US”,“country_code”:“US”,“description”:“Orientals are passionate about the people in their lives. They become extremely attached to their humans, so be prepared for a lifetime commitment. When you are not available to entertain her, an Oriental will divert herself by jumping on top of the refrigerator, opening drawers, seeking out new hideaways.”,“life_span”:“12 - 14”,“indoor”:0,“lap”:1,“alt_names”:“Foreign Type”,“adaptability”:5,“affection_level”:5,“child_friendly”:4,“dog_friendly”:5,“energy_level”:5,“grooming”:1,“health_issues”:3,“intelligence”:5,“shedding_level”:3,“social_needs”:5,“stranger_friendly”:3,“vocalisation”:5,“experimental”:0,“hairless”:0,“natural”:0,“rare”:0,“rex”:0,“suppressed_tail”:0,“short_legs”:0,“wikipedia_url”:“https://en.wikipedia.org/wiki/Oriental_Shorthair",“hypoallergenic”:1}],“id”:“xbW2bsXfK”,“url”:“https://cdn2.thecatapi.com/images/xbW2bsXfK.jpg”,“width”:2448,"height”:3264}]

So I did some investigating, and the main reason you’re having issues is the ParseJson function you’re using doesn’t actually work. It parses the JSON object, but won’t actually let you access properties on it like you would any other VB object. You can’t actually access any properties on objects or arrays at all.

The second reason it’s not working is that the root-level value returned by the API is an Array not an Object.

So instead of Result = j.url you would have to do something like this: Result = j(0).url

… except for my first point. Since you can’t actually access the values in an array, you’ll need to find some other way to parse your JSON. I’ve prepared a class and a working example for you:

Sub Include(strScriptName)
    Dim objFSO, objFile
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFile = objFSO.OpenTextFile(strScriptName)
    ExecuteGlobal objFile.ReadAll()
    objFile.Close
End Sub

Sub Cat_OnLoad
    Include("VbsJson.vb")
    Dim http,aURL
    aURL = "https://api.thecatapi.com/v1/images/search"
    Set http = CreateObject("Msxml2.XMLHTTP")

    http.open "GET",aURL,False
    http.send
    strJson = http.responseText
    
    Wscript.Echo ("the URL to get is" & strJson)
    
    Set JSON = New VbsJson
    j = JSON.Decode(strJson)
    Result = j(0)("url")

    Wscript.Echo ("the URL for the image  is " & Result)
End Sub

Notice that I am including a file named “VbsJson.vb”. You can either use my Include subroutine, or just copy+paste the contents into your own script and ignore the Include altogether, if you’d prefer. Either way, you can find this file here:

I would like to point out that parsing the JSON manually (in this case, character-by-character), is also much safer. While I’m sure CreateObject("htmlfile") is sandboxed to some degree, it’s entirely possible that if anyone were to hijack the API URL, they could inject malicious javascript/vb code into your application.

While this is unlikely (and I assume that you’re not using this script in any commercial/live capacity), it’s always safer to avoid any situation where you’re executing dynamically-loaded code.

Hi t3rminus,
Thanks for the detailed answer, but unfortunately not working for me. When I try to use your class in my script, I get a lot of error, mainly about "let and set assingment argument are no longer supported" and other errors about prantheses expected and a few others.
I don’t have Visiual Studio installed, all the scripting I am doing is within the enviornment of this application I am working with,
Not sure if you can help me, but appriciate your effort.

Let me know what the full errors are, and I can post an edited class. Or you can let me know which application you’re using, and I can try and re-create your environment.

Again thanks for your offer to help and I am very appricative of your support so far. But I am a bit unsure. My script posted above works well with two other API’s namely https://sv443.net/jokeapi/category/Programming and
https://api.chucknorris.io/jokes/random
I can easily get any of the JSON tags using the script above.
And as I pointed out earlier, both the above URL pass the test at https://jsonformatter.curiousconcept.com where as the Cat and Dog API fail as mentioned above.
I am no programmer, so may be on to a red herring, but could you look into this again and making sure the cat API’s JSON result meets the JSON standards?
Thanks again,

@SunnySydney The JSON being returned is valid. You can verify the result by copying and pasting it into the formatter.

The reason you’re seeing this error is because the formatter does not include an API key when making the request server-side, which is required. The only way to validate the JSON would be to copy+paste the result.

The reason those other APIs are working with your code is that they return an Object directly. TheCatApi returns an Array, which I explained already-- doesn’t appear to be usable with your method of parsing JSON.

If you only care about the first result, here is a work-around.
Note that if you’re using this same ParseJson function for other API calls, you will need to make a separate function for APIs with Array results like TheCatApi.

Function ParseJson(strJson)
    WScript.echo(strJson)
    Set html = CreateObject("htmlfile")
    Set window = html.parentWindow
    window.execScript "var json = (" & strJson &")[0]", "JScript"
    Set ParseJson = window.json
End Function

Note the changes to the line:
window.execScript "var json = (" & strJson &")[0]", "JScript"
I am extracting the first element in the array with [0] before it is returned.

Then the result becomes a valid Object and is usable by the rest of your code.

Edit:
Make sure you register for, and include an API Key with your requests using:

http.setRequestHeader "x-api-key", "YOUR_API_KEY_HERE"

And since you’re only ever using the first result, it would be wise to save bandwidth by adding ?limit=1 to your URL. An array will still be returned, but there will be only one result.

All makes sense now, thanks for the detailed explanations and examples. I can’t thank you enought. really appricate this. I will also update once I have implemented the suggestions.
regards.

Just tested today and it works well. Thanks for your support and paitence.

regards,