Urlfetch json with query validation

I am trying to make a command that fetches some json, this part works.

I would like to check if the query successfully fetches json before proceding, so that chat doesn’t get spammed with unexpected identifier (thanks for ruining this combination of 2 words for me btw LUL)

Here’s what I have so far:

 !addcom !pokemove $(eval
let apitest = `$(urlfetch json https://pokeapi.co/api/v2/move/$(query))`; 
`${apitest}`.includes(`Server`) ? `Please use - instead of space or a real move FeelsOkayMan` : apitest;
let api = $(urlfetch json https://pokeapi.co/api/v2/move/$(query)); 
`${api["name"]} : ${api["power"]} pow ${api["accuracy"]} acc ${api["damage_class"]["name"]} ${api["type"]["name"]}`;)

Line 2 sets a the response as a string
Line 3 checks the string for the substring “Server” (if the response is an error it contains “Remote Server Returned Code 404” as a string, not json) and if it does contain that substring it sends the error message “Please use - instead of space or a real move FeelsOkayMan”
Line 4 sets the response as a urlfetch response object.
Line 5 returns the information required from the response.

Here is the actual and expected behaviour:

Input 1
!pokemove draco-meteor
Expected
draco-meteor : 130 pow 90 acc special dragon
Actual
draco-meteor : 130 pow 90 acc special dragon

Input 2
!pokemove draco meteor
Expected
Please use - instead of space or a real move FeelsOkayMan
Actual
Unexpected identifier

Input 3
!pokemove hyper-beam
Expected
hyper-beam : 150 pow 90 acc special normal
Actual
hyper-beam : 150 pow 90 acc special normal

Input 4
!pokemove hyper beam
Expected
Please use - instead of space or a real move FeelsOkayMan
Actual
Unexpected identifier

If you remove lines 4 and 5 then the command returns the FeelsOkayMan error message correctly for Input 2 and 4 but obviously doesn’t return the correct response for Inputs 1 and 3.

Hey @slicedfred!

How about we automatically replace the space with a dash? This will require two commands, the latter being the alias of the former, but it’ll fix your issue, so here’s what I’m suggesting:

!addcom !pokemove -a=_pokemove $(eval `$(query)`.replace(' ', '-');)

And you don’t need to call the API twice to test it, simply test if one of the key you’re reading is present:

!addcom _pokemove $(eval const api = $(urlfetch json https://pokeapi.co/api/v2/move/$(query)); api.name ? `${api.name}: ${api.power} pow ${api.accuracy} acc ${api.damage_class.name} ${api.type.name}` : 'Please use a real move FeelsOkayMan';)

Hi @Emily

Thanks a lot these meets all the inputs I mentioned :slight_smile:
However, I think because the error message when the move doesn’t exist isn’t json the error check fails so unexpected identifier is returned when the query is a non-move like “test”
If you have any ideas to get the FeelsOkayMan message to appear when a non-move is queried I would be very interested.

The command is working a lot better now though so thank you, I will see if I can cover the non-move case myself as well.

1 Like

Yeah, I went to test the command just to make sure I gave you code that worked, and I get some issues…

The API is badly build, it shouldn’t include comments in the response, those should be in a key instead, and we should have a status key as well so we always get a response, even a 404.

I tried the following code, but because of the comments it breaks the code:

$(eval let error = 0; let api = '$(urlfetch json https://pokeapi.co/api/v2/move/$(query))'; !api.includes('Code 404') ? api = JSON.parse(api) : error = 1; error === 0 ? `${api.name}: ${api.power} pow ${api.accuracy} acc ${api.damage_class.name} ${api.type.name}` : 'Please use a real move FeelsOkayMan';)

I think you can get around this issue by doing it like you did before: with two API calls.


Testing for the presence of a key should be enough if the API was correctly built, but with your two-API-calls workaround, you should manage to get it working.

Hi @Emily

I’m back to the unexpected identifiers again, I think I lack some critical understanding regarding something about using multiple api calls, this is what I have:

!editcom _pokemove $(eval 
let error = 0; 
let apitest = '$(urlfetch json https://pokeapi.co/api/v2/move/$(query))';
!apitest.includes('Code 404') ? let api = $(urlfetch json https://pokeapi.co/api/v2/move/$(query)) : error = 1; 
error === 0 ? `${api.name}: ${api.power} pow ${api.accuracy} acc ${api.damage_class.name} ${api.type.name}` : 'Please use a real move FeelsOkayMan';)

As far as I can tell it works up until line 4 but I can’t get the code to use the json response.

I don’t suppose you can help?

I was thinking about doing it like you did in your first message, so like this:

!addcom _pokemove $(eval const apiTest = `$(urlfetch json https://pokeapi.co/api/v2/move/$(query))`; const api = $(urlfetch json https://pokeapi.co/api/v2/move/$(query)); !apiTest.includes('Code 404') ? `${api.name}: ${api.power} pow ${api.accuracy} acc ${api.damage_class.name} ${api.type.name}` : 'Please use a real move FeelsOkayMan';)

But unfortunately it seems the issue shows up simply because we call the API without containing it inside of a string.

It looks like there’s no way to win on that one: either we contain the API response inside of a string, but then we can’t parse the JSON to exploit it because it’s badly formatted, or we don’t contain the response in a string so we are able to exploit it if needed, but then we get errors like these…

Thanks for looking into it.

Would it be possible to do the api call as a string in the first command with the hyphen replacement and pass the error variable to the 2nd command and do the api call as a json?

Ha-ha! I see you’re thinking like me! That’s the last thing I was trying, and I found a hacky way to make it work like you want it to; however, we can’t do the hyphen replacement anymore, this is due to the fact that $(urlfetch) are called before the actual command code is executed, but at least this works: it gives a response when the request is properly formatted, otherwise it gives an error that explains how to format the request properly.

!addcom !pokemove -a=_pokemove $(eval const apiTest = `$(urlfetch json https://pokeapi.co/api/v2/move/$(query))`; apiTest.includes('Code 404') ? ' ' : '$(query)';)

!addcom _pokemove $(eval const api = $(urlfetch json https://pokeapi.co/api/v2/move/$(query)); api.name ? `${api.name}: ${api.power} pow ${api.accuracy} acc ${api.damage_class.name} ${api.type.name}` : 'Please use - instead of space or a real move FeelsOkayMan';)

Yes! You did it!
I think using an alias was the secret, I think i understand why my attempts were going wrong given the urlfetches are done first.

Not ideal as we discussed but I think this is the best version of the command, thanks a lot.

I can use this as a template for other commands using that API, assuming it is coded just as badly for other endpoints :laughing:

1 Like

Yup, exactly, aliases are the only way to edit the request before it’s sent to an API. :sweat_smile:

And here it can be used to test the API for errors before exploiting it since otherwise we get an error that breaks the code, so we have to contain the reply some way; note that I’ve used backticks to surround the first API response where we might get an error, single quotes were throwing an error when it was responding properly.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.