Search code examples
javascriptjavascript-objectsheremaps

Append a key/value pair to preexisting method that returns an object


I'm using the Heremaps API geocode method and I'm wondering if there is a way that I can append my own key/value pair that is an id of the record address that I'm running through the Heremaps API. The problem I'm running into is that the geocode method only takes an address parameter that it adds to the geocode endpoint call as its query string, but it doesn't accept any more arguments. I'm trying to come up with a way to call the geocode method with my address and append the record ID into the object that is returned so that each address that the API returns, has its original ID.

Since I can't change the geocode method because it's being called from a cdn https://js.api.here.com/v3/3.1/mapsjs-service.js, I need to append the record ID to the address that's being returned.

I added a coupleGeocodeRecordID function to attempt to couple the record ID with the object returned from geocode function call but it returns an error

Uncaught (in promise) TypeError: can't access property 1533, geoCoder(...) is undefined

app.js that makes the API call to the database to retrieve the record IDs (3), location names (6) and addresses (13) in the refSrcData const. The fetchAll call is just an API call to the database to pull these values.

const refSrcData = {
    from: 'xxxxxxx',
    select: [3, 6, 13],
};

const fetchAll = () => {
    fetch('call to the endpoint', {
            method: 'GET',
            headers: {
                'QB-Realm-Hostname': 'xxxxxxxxx',
                Authorization: 'xxxxxxxxxxxxxxx',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(refSrcData),
        })
        .then(resp => resp.json())
        .then(data => {
            getRefAddresses(data);
        })
        .catch(error => console.log('Error:', error));
};

// Step 1: initialize communication with the platform
const platform = new H.service.Platform({
    apikey: 'xxxxxxxxxxxxxxxxxxxxx',
});

// Get an instance of the geocoding service:
const service = platform.getSearchService();

// Call the geocode method with the geocoding parameters,
// the callback and an error callback function (called if a
// communication error occurs):
const geoCoder = address => {
    try {
        service.geocode({
                q: address,
            },
            result => {
                // Add a marker for each location found
                result.items.forEach(item => {
                    console.log(item);
                });
            }
        );
    } catch (err) {
        console.log(err, `Can't reach the remote server`);
    }
};


// Write a function that handles the record ID and couples with the geocode data
const coupleGeocodeRecordID = (address, recordId) => {
    geoCoder(address)[recId] = recordId;
};

const getRefAddresses = async dataObject => {
    const recordId = dataObject.data.map(e => e['3'].value);
    const refAddress = dataObject.data.map(e => e['6'].value);
    const refName = dataObject.data.map(e => e['13'].value);

    for (let i = 0; i <= 10; i++) {
        let location = refAddress[i];
        location.length > 0
            ?
            await coupleGeocodeRecordID(location, recordId[i]) :
            false;
    }
};

window.onload = () => {
    fetchAll();
};

This is what is returned when I call the geocode function. I'm trying to attach the record ID to each object. geocode returns these objects


Solution

  • There are two problems:

    • Your geoCoder() function was not returning the result after the search. It was only logging it to the console. (You have to use promises with the geocode API, but promises work with async / await. I hope it makes sense)
    • Your coupleGeocodeRecordId() function is not doing anything with the results. I assume you plan to use them somehow. (Here, they are stored in an object called results for later use.)

    I modified those two functions. The rest of your code looks fine, probably.

    I can't test this code, so I don't know if there are other problems with how you're using the API.

    const results = {};
    
    const geoCoder = address => new Promise( finish => {
        try {
    
            //try to run the search.
            service.geocode(
                { q: address, },
                finish //on success, resolve the promise with the result
            );
    
        } catch ( err ) {
    
            console.error( "Can't reach the remote server.", err );
    
            finish( null ); //on failure, resolve the promise with null
    
        }
    } );
    
    const coupleGeocodeRecordID = async ( address, recordId ) => {
    
        //try to get a search result.
        const result = await geoCoder( address );
    
        if( result ) {
    
            //attach the record id to the search result
            result.recordId = recordId;
    
            //store the result for use? I don't know what these are for
            results[ address ] = result;
    
        }
    
    }