Angular's $q is a powerful tool for handling asynchronous operations, while

I've been struggling for hours trying to figure out how $q works. I'm attempting to use it with a function from the google.maps API, but I just can't seem to grasp it on my own. Maybe I completely misunderstand $q. Can someone help me or provide some insight?

Here's a simple example of what I'm trying to accomplish:

var geocoder = new google.maps.Geocoder();
let promise1 = geocoder.geocode({address: "someAddress"});
let promise2 = geocoder.geocode({address: "someOtherAddress"});
$q.all([promise1, promise2]).then(data => { 
    console.log(data) 
});

//The output I'm getting is: [undefined, undefined], which is not what I expected.

Where am I making mistakes? Here's the original async method from the Google API that works fine.

var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: "someAddress"}, function(response, status){
    if(status === 'ok')
        //Do what I need with the response
    else
        //Do something else
});

I want to work with multiple requests, not just one. So, I need to store all the responses (and wait for them as it's an async function) before proceeding. That's why I'm trying to use $q to achieve my goal.

PS: I know there are many discussions about $q, but even after hours of researching, I can't seem to find a solution. Please don't suggest googling it.

Thanks in advance for your help!

Answer №1

.geocode does not return a Promise, it uses a callback mechanism and as you have discovered, it returns undefined.

If you want to create a geocode function that returns a Promise, you can do so by:

const geocodePromise = (geocoder, params) => new Promise((resolve, reject)  => {
    geocoder.geocode(params, function(response, status) {
        if (status == 'ok') resolve(response);
        else reject(status);
    });
});

var geocoder = new google.maps.Geocoder();
let promise1 = geocodePromise(geocoder, {address: "someAddress"});
let promise2 = geocodePromise(geocoder, {address: "someOtherAddress"});
$q.all([promise1, promise2]).then(data => { 
    console.log(data) 
});

Alternatively, you can define a `geocodeP` method on the `google.maps.Geocoder` object:

google.maps.Geocoder.geocodeP = function geocodeP(params) {
    return new Promise((resolve, reject) => {
        this.geocode(params, function(response, status) {
            if (status == 'ok') resolve(response);
            else reject(status);
        });
    });
};
var geocoder = new google.maps.Geocoder();
let promise1 = geocoder.geocodeP({address: "someAddress"});
let promise2 = geocoder.geocodeP({address: "someOtherAddress"});
$q.all([promise1, promise2]).then(data => { 
    console.log(data) 
});

Answer №2

Which node module are you utilizing? Is it google-maps-api?

geocoder.geocode({address: "someAddress"});

Does it return a promise, or should you try this:

geocoder.geocode({address: "someAddress"}).then(data => console.log(data));

If it returns undefined, then the issue may lie with the API itself.

If data is not undefined, then the problem is not caused by the geocoder.geocode() part.

You can explore this library Get states of tasks ran by bluebird.all().spread()

Regarding the "double thread" you mentioned, JavaScript does not support multithreading. More information can be found at Why doesn't JavaScript support multithreading?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Skip waiting for all resolves to complete before showing the views in ui-router

My current setup involves using ui-router to load various subviews within a certain state. However, some of these views require resources that have a long resolution time. I want to display the other views as soon as they are ready. This is how I am fetch ...

Creating an Angular 2 service that relies on other services, while allowing components to inject only the parent service

In the scenario where a ParentService depends on ChildService, it is important to list both services in the "providers" attribute of the @Component definition. Is there a method to configure ParentService to automatically inject ChildService, simplifying ...

Having trouble parsing data in a jQuery REST call

After creating a web service using Slim Framework 3 in PHP, all data is returned using the following instruction: return $response->withJson($liste); I then created an HTML client using the "jquery.rest" plugin to view the JSON results. However, I am ...

Analyzing an array through its sub arrays

Imagine we are dealing with an array of varying length and we need to process it in chunks of maximum size 100, aiming to use the fewest number of chunks. For example, if the array's length is 241, we would need to divide it into 3 subarrays: 41, 100, ...

Instead of displaying the content, Facebook is now displaying angular brackets when sharing posts

Even though AngularJS is rendering the content correctly in title and meta tags, when sharing it on platforms like facebook or google, it displays as angular {{ }} in the popup window. Code: <div ng-controller="MyCtrl"> <title>{{mDetails.di ...

What is the process for incorporating a full-page blog into a blog preview?

I customized a template, but there is a blog section within the div that I am struggling to replicate. Here is the test website for reference: Below is the HTML code for the blog section: <!-- Blog Start --> <section class="section bg ...

Attempting to transpile JavaScript or TypeScript files for compatibility within a Node environment

Our node environment requires that our JavaScript files undergo Babel processing. Figuring out how to handle this has been manageable. The challenge lies in the fact that we have a mix of file types including .js, .jsx, .ts, and .tsx, which is not subject ...

Fill various dropdowns with a list or array of values discreetly without displaying the populated values on the visible interface

I have an array with values 1,2,3,4. Using an add function, I am able to create multiple dropdowns. By default, the first dropdown always has a value of one when initially set up. When we press add and populate the second dropdown with values 2,3,4, tho ...

What is preventing me from sending a POST request to my Node.js Express server?

Currently, my goal is to develop a straightforward user registration system. I simply wish to register through the HTML form and then be able to log it in the server using console.log. However, when attempting to achieve this with fetch, I encountered the ...

Add a custom text with a precise offset in the Highcharts column chart

Is there a way to insert text at a particular position within highcharts? ...

What's the best way to retrieve a value from a function that invokes itself multiple times?

My task involves navigating through nested object data to find a specific result. I am using the findByKey function, which recursively calls itself until the desired result is found. However, instead of returning object.source, I am getting undefined. as ...

Unblocking the context menu: How entering JS directly into the address bar compares to using a bookmark

Exploring the concept of blocking the context menu using JavaScript. Here's how you can block such a menu: document.addEventListener('contextmenu', event => event.preventDefault()); I recently came across an article that mentioned this ...

Basic exam but located in a place that is not valid

Here is a test I am working on: // import {by, element, browser} from "protractor"; describe('intro', () => { beforeEach(() => { browser.get(''); }); it('should have multiple pages', () => { let buttonOn ...

What is the process of generating enum values using ES6 in Node.js?

Can JavaScript support enumerations with assigned integer values, similar to how other programming languages handle it? In C#, for instance, I can define an enum as follows: enum WeekDays { Monday = 0, Tuesday =1, Wednesday = 2, Thursday ...

Error encountered in a Node.js Express application: 'Error in Jade template (version 1.0+): The usage of duplicate key "id" is not permitted.'

Seeking guidance on the following issue: Within my Express app, I am providing numerous parameters to a Jade template, resulting in an error message that states: Duplicate key "id" is not allowed. (After reviewing, I have confirmed that there is no para ...

Console displaying a 400 bad request error for an HTTP PUT request

I'm currently in the process of developing a react CRUD application using Strapi as the REST API. Everything is working smoothly with the GET, DELETE, and CREATE requests, but I encounter a 400 bad request error when attempting to make a PUT request. ...

Tips on storing chosen language in local storage or cookies using AngularJS

As a newcomer to angularjs, I am facing the challenge of saving the selected language from a dropdown menu in HTML to either local storage or cookies. This way, when a user navigates to another page, the language they previously chose will be loaded and us ...

Issues arise with objects disappearing when zooming out in Three.js

In my current three.js project, I have encountered an issue with the z position of my camera. Whenever the z position is set too high, the scene turns completely black when zooming out, which is not the desired outcome. Specifically, with camera.position. ...

Is it possible to combine Angular routing with MVC Partial Views?

I am looking to integrate Angular templates into most of my application, but for certain pages, I would like to utilize aspnet MVC controllers and partial views displayed within ng-view. My attempts with routing have looked something like this: when(&apo ...

Learn how to use Cocos2d 2.1.4 to load text, strings, and JSON in HTML

Struggling to upload a large string to my project to use as a matrix, I've run into issues trying to load a text file or json into my HTML5 project. While I've seen it can be done in 3.0 using cocos2d, I'm wondering if there's a way to ...