Skip to content

Commit

Permalink
Merge pull request #143 from tightenco/debug/96-object-keys
Browse files Browse the repository at this point in the history
Handle situations where a single model object is passed into URL.
  • Loading branch information
DanielCoulbourne authored Apr 14, 2018
2 parents 24192a2 + ce8cf8e commit c6d5cc8
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 28 deletions.
36 changes: 23 additions & 13 deletions dist/js/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ var Router = function (_String) {

_this.name = name;
_this.absolute = absolute;
_this.urlParams = _this.normalizeParams(params);
_this.template = _this.name ? new __WEBPACK_IMPORTED_MODULE_0__UrlBuilder__["a" /* default */](name, absolute).construct() : '', _this.urlParams = _this.normalizeParams(params);
_this.queryParams = _this.normalizeParams(params);
return _this;
}
Expand All @@ -115,9 +115,19 @@ var Router = function (_String) {
value: function normalizeParams(params) {
if (typeof params === 'undefined') return {};

// If you passed in a string or integer, wrap it in an array
params = (typeof params === 'undefined' ? 'undefined' : _typeof(params)) !== 'object' ? [params] : params;
this.numericParamIndices = Array.isArray(params);

// If the tags object contains an ID and there isn't an ID param in the
// url template, they probably passed in a single model object and we should
// wrap this in an array. This could be slightly dangerous and I want to find
// a better solution for this rare case.

if (params.hasOwnProperty('id') && this.template.indexOf('{id}') == -1) {
params = [params.id];
}

this.numericParamIndices = Array.isArray(params);
return _extends({}, params);
}
}, {
Expand All @@ -135,23 +145,24 @@ var Router = function (_String) {
}, {
key: 'hydrateUrl',
value: function hydrateUrl() {
var _this2 = this;

var tags = this.urlParams,
paramsArrayKey = 0,
template = new __WEBPACK_IMPORTED_MODULE_0__UrlBuilder__["a" /* default */](this.name, this.absolute).construct(),
params = template.match(/{([^}]+)}/gi),
params = this.template.match(/{([^}]+)}/gi),
needDefaultParams = false;

if (params && params.length != Object.keys(tags).length) {
needDefaultParams = true;
}

return template.replace(/{([^}]+)}/gi, function (tag) {
return this.template.replace(/{([^}]+)}/gi, function (tag, i) {
var keyName = tag.replace(/\{|\}/gi, '').replace(/\?$/, ''),
key = this.numericParamIndices ? paramsArrayKey : keyName,
key = _this2.numericParamIndices ? paramsArrayKey : keyName,
defaultParameter = Ziggy.defaultParameters[keyName];

if (defaultParameter && needDefaultParams) {
if (this.numericParamIndices) {
if (_this2.numericParamIndices) {
tags = Object.values(tags);
tags.splice(key, 0, defaultParameter);
} else {
Expand All @@ -161,26 +172,25 @@ var Router = function (_String) {

paramsArrayKey++;
if (typeof tags[key] !== 'undefined') {
delete this.queryParams[key];
delete _this2.queryParams[key];
return tags[key].id || encodeURIComponent(tags[key]);
}
if (tag.indexOf('?') === -1) {
throw new Error('Ziggy Error: \'' + keyName + '\' key is required for route \'' + this.name + '\'');
throw new Error('Ziggy Error: \'' + keyName + '\' key is required for route \'' + _this2.name + '\'');
} else {
return '';
}
}.bind(this));
});
}
}, {
key: 'matchUrl',
value: function matchUrl() {
var tags = this.urlParams,
paramsArrayKey = 0,
template = new __WEBPACK_IMPORTED_MODULE_0__UrlBuilder__["a" /* default */](this.name, this.absolute).construct();
paramsArrayKey = 0;

var windowUrl = window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '') + window.location.pathname;

var searchTemplate = template.replace(/(\{[^\}]*\})/gi, '[^\/\?]+');
var searchTemplate = this.template.replace(/(\{[^\}]*\})/gi, '[^\/\?]+');
var urlWithTrailingSlash = windowUrl.replace(/\/?$/, '/');
return new RegExp("^" + searchTemplate + "\/$").test(urlWithTrailingSlash);
}
Expand Down
2 changes: 1 addition & 1 deletion dist/js/route.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 21 additions & 12 deletions src/js/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,28 @@ class Router extends String {

this.name = name;
this.absolute = absolute;
this.template = this.name ? new UrlBuilder(name, absolute).construct() : '',
this.urlParams = this.normalizeParams(params);
this.queryParams = this.normalizeParams(params);
}

normalizeParams(params) {
if (typeof params === 'undefined')
if (typeof params === 'undefined')
return {};

// If you passed in a string or integer, wrap it in an array
params = typeof params !== 'object' ? [params] : params;
this.numericParamIndices = Array.isArray(params);

// If the tags object contains an ID and there isn't an ID param in the
// url template, they probably passed in a single model object and we should
// wrap this in an array. This could be slightly dangerous and I want to find
// a better solution for this rare case.

if (params.hasOwnProperty('id') && this.template.indexOf('{id}') == -1) {
params = [params.id];
}

this.numericParamIndices = Array.isArray(params);
return Object.assign({}, params);
}

Expand All @@ -33,18 +44,17 @@ class Router extends String {
hydrateUrl() {
let tags = this.urlParams,
paramsArrayKey = 0,
template = new UrlBuilder(this.name, this.absolute).construct(),
params = template.match(/{([^}]+)}/gi),
params = this.template.match(/{([^}]+)}/gi),
needDefaultParams = false;

if (params && params.length != Object.keys(tags).length) {
needDefaultParams = true
}

return template.replace(
return this.template.replace(
/{([^}]+)}/gi,
function (tag) {
let keyName = tag.replace(/\{|\}/gi, '').replace(/\?$/, ''),
(tag, i) => {
let keyName = tag.replace(/\{|\}/gi, '').replace(/\?$/, ''),
key = this.numericParamIndices ? paramsArrayKey : keyName,
defaultParameter = Ziggy.defaultParameters[keyName];

Expand All @@ -67,18 +77,17 @@ class Router extends String {
} else {
return '';
}
}.bind(this)
}
);
}

matchUrl() {
let tags = this.urlParams,
paramsArrayKey = 0,
template = new UrlBuilder(this.name, this.absolute).construct();

paramsArrayKey = 0;

let windowUrl = window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '') + window.location.pathname;

let searchTemplate = template.replace(/(\{[^\}]*\})/gi, '[^\/\?]+');
let searchTemplate = this.template.replace(/(\{[^\}]*\})/gi, '[^\/\?]+');
let urlWithTrailingSlash = windowUrl.replace(/\/?$/, '/');
return new RegExp("^" + searchTemplate + "\/$").test(urlWithTrailingSlash);
}
Expand Down
Loading

0 comments on commit c6d5cc8

Please # to comment.