Inject query parameter into dependency provider factory in Angular

1k views Asked by At

I want a value from the window.location search parameters passed to the body of a dependency provider factory, ideally in an idiomatic Angular way.

Use case: writing my first Angular app I have the app running on one port and the backend server on another. I want to append &backend=localhost:12345 to the URL to have the app talk to that host. This is read-only, hand-written to the URL bar. I don't want to navigate to such a URL.

Approaches considered:

  1. Use window.location.href directly. Makes the code depend on a browser, potentially breaking test fixtures or anything else that wants to execute the code outside a browser.
  2. Use PlatformLocation.href. The doc says “this class should not be used directly by an application developer.”
  3. Use Location.path(). Seems to work, but also seems to not offer any way to access the full URL. The stand-alone path includes the query parameter, but appears to be invalid as an argument to the URL constructor, so I ended up with something like new URL('http://no-such-host/' + location.path()).searchParams.get('backend'). Hardly elegant.
  4. Use ActivatedRoute.queryParams somehow. Injecting an ActivatedRoute into my factory apparently gives me a default instance (stringifies as Route(url:'', path:'')) so the query parameters seem to be absent. And the queryParams method returns an Observable, while from what I read on the net, using asynchronous code flow for a provider factory is tricky at best.

Is there a better way to let a factory make decisions based on a query parameter?

1

There are 1 answers

2
Mateus Carniatto On

If I understand correctly you want to take the query param backend from your path programatically.

You can use the Angular Router like the example below:

@Service()
export class MyFactory {
  constructor(private route: ActivatedRoute) {}

  fetch() {
    const backendUrl = route.snapshot.queryParams['backend'] || 'defaultUrl';

    // do something here
  }
}

Alternatively, you could use the Location object to get the query param like bellow:

const backendUrl = new URLSearchParams(Location.search).get('backend');

// do something here