API Calls within Tools

Hi! I was trying to create a new Weather tool using an API call and was wondering if this is possible to do within a tool? I tried having a separate javascript file and trying to link it through the script tag within my tool but it does not seem to be working. Also for context, the API method I am using is XMLhttprequest

It’s possible that the Toolbox’s safari web view is blocking the request due to CORS. Can you share the code you’re working with?

Yup! Here is the previous file: https://drive.google.com/drive/folders/1aVo3kttwYPk8WrSISpEOShcHKBpTQlz3?usp=sharing

I am currently trying to work with using fetch instead of xml to see if that will make a difference. Thanks for the help!

@jhobin I am trying to do something like:

const fetch = require("node-fetch");
    var temp;
    fetch('http://api.weatherapi.com/v1/current.json?key=b05d83123b5e426baed184558202606&q=19050')
        .then(response => response.json())
        .then(data => {
        temp = data
        console.log(temp);
        console.log("Info I want:");
        console.log(temp.current.temp_f);
        text.innerText = temp.current.temp_f;
        // run your function here!
    }); 

however, it still does not seem to update my label tool

One thing to keep in mind is that the file index.html is run in the browser, not on node. You can just use the fetch api command you put above without the require and it should work perfectly.

I took out that line just now, however I am still running into the issue where it does not update the label. I think it may have to do with me doing text.innerText within the fetch rather than outside of that function. But I was a bit confused on how I could save that fetch data to do text.innerText outside the function such that it will do the api call first and then update the text.

Hi @Emun13, I went and tested your code, and also tried to create my own tool that would make an HTTP GET request to an external API. However, I ran into the same issue.

I think the underlying issue, as @jhobin mentioned, is that the tool’s code runs in the Toolbox’s safari web view, which is blocking cross-origin requests. This is different from the logic blocks, whose code gets executed on the Node.js Edge Server.

I think the solution would be for us to create an API that proxies your tools’ GET requests through the Edge Server. Something like spatialInterface.httpGet(url, callback) which would send a message to the Edge Server telling it to make the HTTP request on behalf of the tool, and then trigger the callback when the app receives the response from the server.

This is the code I tried using in the tool, by the way, which ran into the CORS error:

function getData(url, callback) {
    var req = new XMLHttpRequest();
    try {
        req.open('GET', url, true);
        req.onreadystatechange = function () {
            if (req.readyState === 4) {
                if (req.status === 200) {
                    if (req.responseText) { callback(req.responseText, null); }
                } else {
                    callback(null, 'error');
                }
            }
        };
        req.send();
    } catch (e) {
        callback(null, 'error');
        console.log('could not connect to ' + url);
    }
}

getData('https://postman-echo.com/get?foo1=bar1&foo2=bar2', function(res, err) {
    console.log(res, err);
});

@ben Thank you for your response! I was able to figure it out this morning :slight_smile: Here’s an example:

1 Like

Amazing work! Can you share how you accomplished this? I’ve been struggling with it and would love to learn :slight_smile:

Yup! Here is the link to the zip of the folder: https://drive.google.com/file/d/1mUJikCM7hHjTwN2bDCy1VGoBeX5xNi9U/view?usp=sharing

If you download it and put it into the tools folder within the spatial-core-addon it should work. I am still editing it a bit because right now the city name that appears does not resize to the window of the AR visualization.

1 Like

That’s awesome! I added your tool to my add-on and it worked perfectly for me. :raised_hands:

1 Like

That’s Amazing!!

Hey @ben and @jhobin! I am trying to make an API call to a heroku server we have to run an FFT with the following code:

function herokurequest(arr, fs){
arr = [0, 10, 1, 0];
var xmlHttp = new XMLHttpRequest();
var url = "http://ptc-fft-server.herokuapp.com/fft/raw_fft";
// this is the format for a propvalue to update airtable
var body = JSON.stringify({
    "amplitude": arr, 
    "sampling_rate": fs,
    "percentage": 0.5
})
xmlHttp.open("POST", url, false);
xmlHttp.setRequestHeader("Content-Type","application/json");
xmlHttp.setRequestHeader("Accept","application/json");
xmlHttp.onreadystatechange = function() {
    if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        // console.log(xmlHttp.responseText);
        return JSON.parse(xmlHttp.responseText);
        
        // console.log(response.magnitude);
        // console.log(response.frequencies); 
		// console.log(xmlHttp.responseText.frequencies)
    }
    else{
    	// console.log(xmlHttp.status);
    	return "HERE!!!!"
	}
};
xmlHttp.send(body);
return xmlHttp.responseText;
} 

This code runs successfully if it is a .js file however when I run the same exact code within the Toolbox (in an html file), it gives me a status code 0. Do y’all happen to have any thought on why this might be happening?

Sorry for the delay in responding! This got lost in my inbox. I would first make sure the server has cors enabled (https://expressjs.com/en/resources/middleware/cors.html is one way)