Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

feat($location): add queryString method #2701

Closed
wants to merge 1 commit into from

Conversation

joshrtay
Copy link
Contributor

Added new queyString method to locationProvider to allow for custom query string parsers. The method expects an object with a stringify function for encoding and a parse function for decoding.

For example you could use node-querystring:

var qs = require('qs');
$locationProvider.queryString(qs);

or JSON:

$locationProvider.queryString(JSON);

Added new queyString method to locationProvider to allow for
custom query string parsers.
@petebacondarwin
Copy link
Contributor

I quite like this idea but I think it needs to be thought through carefully as it may allow people to easily break their applications.

@pkozlowski-opensource
Copy link
Member

@petebacondarwin @joshrtay while I also like the addition but shouldn't it become a regular service? It seems to have 2 methods on it: query string parser with stringify and parse functions

@joshrtay
Copy link
Contributor Author

@petebacondarwin since the parser has to be set explicitly, shouldn't it be the dev's job to make sure it doesn't break their application?

@joshrtay
Copy link
Contributor Author

@pkozlowski-opensource setting the query string parser changes the behavior of $location. It seems to me that methods that change the way a service behave are placed on the service provider. queryString expects a parser, which is an object with a parse function and a strinfigy function. JSON and qs are valid parsers.

@petebacondarwin
Copy link
Contributor

@joshrtay

  • services that rely on the query string in $location may or may not break
    if we change the way that they are parsed. While I accept that the
    developer should not change things if they do not know what they are doing,
    it seems that we should minimize the chances of this.
  • you could still expose the queryString parser as an AngularJS service but
    also configure it in a config block. This is what happens when providing
    controllers to $resourceProvider.

On 20 May 2013 17:08, joshrtay [email protected] wrote:

@pkozlowski-opensource https://github.com/pkozlowski-opensource setting
the query string parser changes the behavior of $location. It seems to me
that methods that change the way a service behave are placed on the service
provider. queryString expects a parser, which is an object with a parse
function and a strinfigy function. JSON and qs are valid parsers.


Reply to this email directly or view it on GitHubhttps://github.com//pull/2701#issuecomment-18156010
.

@joshrtay
Copy link
Contributor Author

@petebacondarwin - can you give me an example of what your proposing? I'm not sure I follow.

@kstep
Copy link
Contributor

kstep commented May 21, 2013

@petebacondarwin you are overprotecting. There're a lot of other similar ways to "break" AngularJS, e.g. by using $interpolateProvider.startSymbol() and $interpolateProvider.endSymbol(), why keep these "dangerous" methods?

IMHO, this options provides additional freedom, and given sane default of qs parser, and the fact the option is set explicitly and never changes (b/c it's set in .config() section), I don't see why it shouldn't be merged.

@petebacondarwin
Copy link
Contributor

@kstep - don't worry! I never said this shouldn't be merged. In fact you'll see that I thought it was quite a good idea. I just said that we need to think this through carefully to make sure that it is a sensible addition and won't break anything.

As an example of providing this as a service. I could imagine something like this:

angular.module('my-qs-module', [])
.factory('myQS', function() {
  return {
    parse: function(queryString) { ... },
    stringify: function(paramsObject) { ... }
  };
})
.config(function($locationProvider) {
  $locationProvider.qsProvider('myQS');
});

@joshrtay
Copy link
Contributor Author

@petebacondarwin how is this approach safer than setting the parser directly on the locationProvider? Ultimately the user is still changing the behavior of $location.

This approach would offer some advantages, if angular shipped with a couple query parsers that the user could then select in the config block.

@petebacondarwin
Copy link
Contributor

@joshrtay - it doesn't. It just is an example of what Pawel was suggesting.

Pete
...from my mobile.
On May 22, 2013 4:35 AM, "joshrtay" [email protected] wrote:

@petebacondarwin https://github.com/petebacondarwin how is this
approach safer than setting the parser directly on the locationProvider?
Ultimately the user is still changing the behavior of $location.

This approach would offer some advantages, if angular shipped with a
couple query parsers that the user could then select in the config block.


Reply to this email directly or view it on GitHubhttps://github.com//pull/2701#issuecomment-18255683
.

@pkozlowski-opensource
Copy link
Member

@joshrtay @petebacondarwin - just to clarify - I wasn't suggesting service-based approach to make it "safer" - but rather to make this service reusable. I can see other places where it could potentially fit, $resource and $http being ones that come to my mind. In those services we need to parse objects to query strings as well.

Anyway, this was just a quick suggestion, I don't feel strongly about it. Once again, I'm just noticing that there are other parts of AngularJS where we do need to manipulate query strings (converting to objects and back)

@joshrtay
Copy link
Contributor Author

@pkozlowski-opensource @petebacondarwin so your suggesting a service like:

angular.module('ng').factory('$queryString', function() {
  var parser = {stringify: toKeyValue, parse: parseKeyValue};
  return function(p) {
    if (isDefined(p))
      parser = p;
    else
      return parser;
  }; 
});

that $resource, $location, $http and dev code could use.

I like this approach better. If you guys think it is sufficiently "safe" i'd be happy to implement it.

@pkozlowski-opensource
Copy link
Member

@joshrtay yeh, this is roughly what I was talking about. We could have a default implementation that behaves as it does today and people could override it as needed.

But once again, this was just a quick thought, I will let others to weight here.

@chirayuk
Copy link
Contributor

For the $queryString service, the (de)serialization could depend on the context (domain?). e.g. One resource might require a different strategy than another resource.

@pkozlowski-opensource
Copy link
Member

@chirayuk Yes, but it would mean that someone would interact with different types of back-ends in one app... Not sure how common this might be but you've got a valid point here. In this case we should have ability so specify a custom de-serialization service (function?) per resource.

But yeh, I don't know how common this might be as an use-case...

@petebacondarwin
Copy link
Contributor

Actually I think it is quite common. Consider OAuth, where you might log
in via one service and then access items on another service. Or a mashup
where you want to have a page that displays twitters and Google+ posts
alongside application content.

On 11 July 2013 21:46, Pawel Kozlowski [email protected] wrote:

@chirayuk https://github.com/chirayuk Yes, but it would mean that
someone would interact with different types of back-ends in one app... Not
sure how common this might be but you've got a valid point here. In this
case we should have ability so specify a custom de-serialization service
(function?) per resource.

But yeh, I don't know how common this might be as an use-case...


Reply to this email directly or view it on GitHubhttps://github.com//pull/2701#issuecomment-20841003
.

@petebacondarwin
Copy link
Contributor

I think we should close this PR and look at creating a PR with a more generalized solution, which would need to be overridable on a URL by URL basis. I expect we would provide one or two built in serializers that confirm to a specified interface that people can implement with their own versions. These built-in serializers would be exposed as services and there would be hooks in things like $location, $http and $resource for specifying which of these serialization services to use and when.

@blowsie
Copy link

blowsie commented Mar 18, 2014

Is there an open thread for this? #3213 is closed also.

@kevinfriedheim
Copy link

I second @blowsie 's question - I too have been scraping the interwebs for a reasonable means of shaping querystring as described by @petebacondarwin

@blowsie
Copy link

blowsie commented Aug 29, 2014

Its gone awfully quiet here, any open tickets for this?

@jmendiara
Copy link
Contributor

last @petebacondarwin proposal I think fits best in some scenarios, but adds extra complexity by introspecting into the URL to choose the serializer.
In a $http context, users should be able to choose a querystring serializer/deserializer service per request. Then, adding a requestInterceptor or wrapping the Backend in a custom service in userland, we will be able to customize the $http behaviour with less core complexity
EDIT: PR done and dropped in #7423

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants