-1

Given the URL:

var urlString = "http://somehost:9090/cars;color=red;make=Tesla?page=1&perPage=10"

I'd like some javascript (node) library which i can use to get the matrix parameters (color and make) for the cars path segment, for example:

var url = URL.parse(urlString)
url.pathSegments["cars"].params

would yield

{
  "color": "red",
  "make": "Tesla"
}

Also, ideally such a library should take into consideration proper decoding for path segment parameters, which is not the same decoding as query parameters.

These params (along with a bunch of other useful information concerning urls) are described in more detail in the following article:

https://www.talisman.org/~erlkonig/misc/lunatech%5Ewhat-every-webdev-must-know-about-url-encoding/

I've done plenty of googling, but have come up empty, but hopefully I'm just blind!

Matthew Madson
  • 1,643
  • 13
  • 24
  • 1
    Not a full answer (no encoding/etc stuff), but `urlString.split("?")[0].split("/").pop().split(";").reduce(function (p, c) { var t = c.split("="); if (t.length > 1) { p[t[0]] = t[1]; } return p; }, {});` should do the trick for what you posted. – royhowie Mar 12 '15 at 04:47

2 Answers2

1

I found URI.js. However, if you don't want to use that library, I think this function will do what you're looking for (not so sure about decodeURIComponent):

var urlString = "http://somehost:9090/cars;color=red;make=Tesla?page=1&perPage=10"

var getParams = function (urlString) {
    return decodeURIComponent(urlString) // decode the URL (?)
        .match(/\/((?!.+\/).+)\?/)
            // the regex looks for a slash that is NOT
            // followed by at least one character and eventually another slash
            // given var urlString = "http://somehost:9090/cars;color=red;make=Tesla?page=1&perPage=10"
            // we don't want        -------^              ^                         ^
            // we want this slash                   ------|                         |
            // all the way until this question mark --------------------------------|
            // regex explanation:
            /*
                \/                  first slash
                (                   open capturing group
                    (?!             lookbehind for NOT
                        .+\/        any character followed by a slash (/)
                    )
                    .+              capture one or more characters (greedy) past
                )                   the close of the capturing group and until
                \?                  a question mark
            */
        [1] // match will return two groups, which will look like:
            // ["/cars;color=red;make=Tesla?", "cars;color=red;make=Tesla"]
            // we want the second one (otherwise we'd have to .slice(1,-1) the string)
        .split(";")
            // split it at the semicolons
            // if you know you're always going to have "name" followed by a semicolon,
            // you might consider using .slice(1) on this part, so you can get rid of 
            // the if statement below (still keep the p[c[0]] = c[1] part though )
        .reduce(function (p, c) {
            // split it at the equals sign for a key/value in indices 0 and 1
            c = c.split("=");
            // if the length is greater than one, aka we have a key AND a value
            // e.g., c == ["color", "red"]
            if (c.length > 1) {
                // give the previous object a key of c[0] equal to c[1]
                // i.e., p["color"] = "red"
                p[c[0]] = c[1];
            }
            return p; // return p, so that we can keep adding keys to the object
        }, {}); // we pass an object, which will act as p on the first call
}

console.log(getParams(urlString));  // { color: "red", make: "Tesla" }

Instead of the regular expression, you can also use what I posted in my comment above:

urlString.split("?")[0].split("/").pop().split(";").reduce( /* etc */)

Now I want a Tesla…

royhowie
  • 11,075
  • 14
  • 50
  • 67
  • thanks for posting your code, though I'd much prefer to use a library so I don't have to maintain it :P I took a look at the documentation for URI.js but I didn't find anything that parses out the matrix parameters. They have great support for parsing out query parameters, but as far as I can tell, no support for matrix. =( The hunt continues! – Matthew Madson Mar 16 '15 at 18:36
  • unfortunately I found the feature request for adding matrix parameter support to URI.js so my skimming of the docs was not lacking. For those looking to keep track, the feature request issue is here: https://github.com/medialize/URI.js/issues/181 – Matthew Madson Mar 16 '15 at 18:50
1

I recently wrote a Node.js Middleware for parsing Matrix Parameters. I've specified the rules that it follows and the format of the output that it generates.

So for instance, here's what your app.js looks like:

let app = require ('express') (),
  matrixParser = require ('matrix-parser');

app.use (matrixParser ());

app.get ('/cars*', (req, res) => {
  //notice the asterisk after '/cars'
  console.log (JSON.stringify (req.matrix, null, 2));
  res.send ('Thanks=)');
});

app.listen (9090);

and your URI looks like:

http://localhost:9090/cars;color=red;make=Tesla?page=1&perPage=10

then, you could test the matrix parser feature with curl like:

curl "http://localhost:9090/cars;color=red;make=Tesla?page=1&perPage=10"

Then req.matrix is set to the following object:

[
  {
    "segment": "cars",
    "matrix": {
      "color": "red",
      "make": "Tesla"
    }
  }
]

The query strings (page, per_page) are left untouched (you can see this by simply writing req.query)

Probably too late in writing an answer at this point, but it might still come handly in future.

Here's the repo: https://github.com/duaraghav8/matrix-parser

npm install matrix-parser

EDIT: Sorry for not providing a more elaborate answer with code earlier, this is my first contribution to SO, I'll take some time to get the hang of it.

Raghav Dua
  • 26
  • 1
  • 5
  • thanks, looks promising I'll have to evaluate how it handles encoding / decoding of the matrix param keys and values when I have some spare time. – Matthew Madson Jul 20 '16 at 18:43
  • Sure. Please let me know in case of any confusion or if you think that some portions could be improved – Raghav Dua Jul 22 '16 at 04:33