diff --git a/CHANGELOG.md b/CHANGELOG.md index b165345c..735574e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Last Changes +- [#65](https://github.com/LaxarJS/laxar/issues/65): fixed navigation being broken when parameter values were missing. - [#66](https://github.com/LaxarJS/laxar/issues/66): prevented endless navigation ping pong in flow controller diff --git a/lib/portal/modules/flow.js b/lib/portal/modules/flow.js index fb2530ac..3c3e2cff 100644 --- a/lib/portal/modules/flow.js +++ b/lib/portal/modules/flow.js @@ -254,12 +254,7 @@ define( [ var placeParameters = {}; var params = place.fixedParameters || $routeParams; object.forEach( place.expectedParameters, function( parameterName ) { - if( typeof params[ parameterName ] === 'undefined' ) { - placeParameters[ parameterName ] = null; - } - else { - placeParameters[ parameterName ] = decodePlaceParameter( params[ parameterName ] ); - } + placeParameters[ parameterName ] = decodePlaceParameter( params[ parameterName ] ); } ); return placeParameters; @@ -272,10 +267,7 @@ define( [ var location = '/' + placeName; object.forEach( place.expectedParameters, function( parameterName ) { - location += '/'; - if( parameterName in parameters && parameters[ parameterName ] !== null ) { - location += encodePlaceParameter( parameters[ parameterName ] ); - } + location += '/' + encodePlaceParameter( parameters[ parameterName ] ); } ); return location; @@ -346,10 +338,10 @@ define( [ if( placeName ) { var targetPlace = places_[ placeName ]; var uri = placeName; + var parameters = entryPoint.parameters || {}; object.forEach( targetPlace.expectedParameters, function( parameterName ) { - var param = entryPoint.parameters[ parameterName ] || ''; - uri += '/' + encodePlaceParameter( param ); + uri += '/' + encodePlaceParameter( parameters[ parameterName ] ); } ); return uri; @@ -421,12 +413,18 @@ define( [ /////////////////////////////////////////////////////////////////////////////////////////////////////////// function encodePlaceParameter( value ) { + if( value == null ) { + return '_'; + } return typeof value === 'string' ? value.replace( /\//g, '%2F' ) : value; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// function decodePlaceParameter( value ) { + if( value == null || value === '' || value === '_' ) { + return null; + } return typeof value === 'string' ? value.replace( /%2F/g, '/' ) : value; } diff --git a/lib/portal/modules/spec/flow_spec.js b/lib/portal/modules/spec/flow_spec.js index f6a7686f..bd435e37 100644 --- a/lib/portal/modules/spec/flow_spec.js +++ b/lib/portal/modules/spec/flow_spec.js @@ -404,6 +404,43 @@ define( [ /////////////////////////////////////////////////////////////////////////////////////////////// + it( 'encodes null parameters as underscore (#65)', function() { + eventBus.publish( 'navigateRequest.previous', { + target: 'previous', + data: { + taskId: null + } + } ); + jasmine.Clock.tick( 0 ); + + expect( $location.path ).toHaveBeenCalledWith( '/stepOne/_' ); + } ); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + it( 'decodes underscores as null (#65)', function() { + eventBus.publish.reset(); + $controller( 'portal.FlowController', { + EventBus: eventBus, + place: $route.routes[ '/stepOne' ].resolve.place(), + // for everything apart from / we can rely on angular js to do the encoding + $routeParams: { taskId: '_' }, + ThemeManager: { + getTheme: function() { return 'myTheme'; } + } + } ); + jasmine.Clock.tick( 0 ); + + expect( eventBus.publish ) + .toHaveBeenCalledWith( 'didNavigate.previous', { + target: 'previous', + place: 'stepOne/:taskId', + data: { taskId: null } + }, { sender: 'FlowController' } ); + } ); + + /////////////////////////////////////////////////////////////////////////////////////////////// + describe( 'to the currently active place again', function() { beforeEach( function() {