Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

abstract-state-router

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

abstract-state-router - npm Package Compare versions

Comparing version 2.0.0 to 3.0.0

.travis.yml

222

index.js

@@ -12,2 +12,4 @@ var StateState = require('./state-state')

var combine = require('combine-arrays')
var buildPath = require('page-path-builder')
var StateTransitionManager = require('./state-transition-manager')

@@ -18,3 +20,5 @@ module.exports = function StateProvider(renderer, rootElement, hashRouter) {

var stateProviderEmitter = new EventEmitter()
StateTransitionManager(stateProviderEmitter)
hashRouter = hashRouter || newHashBrownRouter()
current.set('', {})

@@ -24,11 +28,18 @@ var destroyDom = Promise.denodeify(renderer.destroy)

var renderDom = Promise.denodeify(renderer.render)
var resetDom = Promise.denodeify(renderer.reset)
var activeDomApis = {}
var activeStateResolveContent = {}
var activeEmitters = {}
function handleError(e) {
console.log(e.stack || e)
stateProviderEmitter.emit('error', e)
function handleError(event, err) {
if (!stateProviderEmitter.emit(event, err)) {
console.error(err)
}
}
function destroyStateName(stateName) {
activeEmitters[stateName]('destroy')
delete activeEmitters[stateName]
delete activeStateResolveContent[stateName]
return destroyDom(activeDomApis[stateName]).then(function() {

@@ -39,2 +50,9 @@ delete activeDomApis[stateName]

function resetStateName(stateName) {
activeEmitters[stateName]('destroy')
delete activeEmitters[stateName]
delete activeStateResolveContent[stateName]
return resetDom(activeDomApis[stateName])
}
function getChildElementForStateName(stateName) {

@@ -57,2 +75,5 @@ return new Promise(function(resolve) {

return renderDom(childElement, state.template)
}).then(function(domApi) {
activeDomApis[stateName] = domApi
return domApi
})

@@ -62,16 +83,12 @@ }

function renderAll(stateNames) {
return series(stateNames, renderStateName).then(function(domApis) {
combine({
name: stateNames,
domApi: domApis
}).forEach(function(stateAndChild) {
activeDomApis[stateAndChild.name] = stateAndChild.domApi
})
})
return series(stateNames, renderStateName)
}
current.set('', {})
function onRouteChange(state, parameters) {
function stateGo(transition) {
var fullStateName = prototypalStateHolder.applyDefaultChildStates(state.name)
attemptStateChange(fullStateName, parameters, transition)
}
function onRouteChange(state, parameters) {
stateProviderEmitter.go(state.name, parameters)
stateProviderEmitter.emit('stateChangeAttempt', stateGo)
}

@@ -82,3 +99,3 @@

var route = buildRoute(prototypalStateHolder, state.name)
var route = prototypalStateHolder.buildFullStateRoute(state.name)

@@ -88,31 +105,127 @@ hashRouter.add(route, onRouteChange.bind(null, state))

stateProviderEmitter.addState = addState
stateProviderEmitter.go = function go(newStateName, parameters) {
stateProviderEmitter.emit('state change started', newStateName)
var stateComparisonResults = StateComparison(prototypalStateHolder)(current.get().name, current.get().parameters, newStateName, parameters)
var stateChanges = stateChangeLogic(stateComparisonResults)
// { destroy, change, create }
function emit() {
var args = Array.prototype.slice.apply(arguments)
return function() {
return stateProviderEmitter.emit.apply(stateProviderEmitter, args)
}
}
var statesToResolve = stateChanges.change.concat(stateChanges.create).map(prototypalStateHolder.get)
function getStatesToResolve(stateChanges) {
return stateChanges.change.concat(stateChanges.create).map(prototypalStateHolder.get)
}
resolveStates(statesToResolve, parameters).then(function afterResolves(stateResolveResultsObject) {
return series(reverse(stateChanges.destroy), destroyStateName).then(function() {
return renderAll(stateChanges.create).then(function() {
function attemptStateChange(newStateName, parameters, transition) {
function ifNotCancelled(fn) {
return function() {
if (transition.cancelled) {
var err = new Error('The transition to ' + newStateName + 'was cancelled')
err.wasCancelledBySomeoneElse = true
throw err
} else {
return fn.apply(null, arguments)
}
}
}
return prototypalStateHolder.guaranteeAllStatesExist(newStateName)
.then(function applyDefaultParameters() {
var state = prototypalStateHolder.get(newStateName)
var defaultParams = state.defaultQuerystringParameters || {}
var needToApplyDefaults = Object.keys(defaultParams).some(function missingParameterValue(param) {
return !parameters[param]
})
if (needToApplyDefaults) {
throw redirector(newStateName, extend({}, defaultParams, parameters))
}
}).then(ifNotCancelled(emit('stateChangeStart', newStateName, parameters)))
.then(function getStateChanges() {
var stateComparisonResults = StateComparison(prototypalStateHolder)(current.get().name, current.get().parameters, newStateName, parameters)
return stateChangeLogic(stateComparisonResults) // { destroy, change, create }
}).then(ifNotCancelled(function resolveDestroyAndActivateStates(stateChanges) {
return resolveStates(getStatesToResolve(stateChanges), parameters).catch(function onResolveError(e) {
e.stateChangeError = true
throw e
}).then(ifNotCancelled(function destroyAndActivate(stateResolveResultsObject) {
transition.cancellable = false
function activateAll() {
var statesToActivate = stateChanges.change.concat(stateChanges.create)
statesToActivate.map(prototypalStateHolder.get).forEach(function(state) {
try {
state.activate(activeDomApis[state.name], state.data, parameters, getContentObject(stateResolveResultsObject, state.name))
} catch (e) {
handleError(e)
}
return activateStates(statesToActivate)
}
extend(activeStateResolveContent, stateResolveResultsObject)
return series(reverse(stateChanges.destroy), destroyStateName).then(function() {
return series(reverse(stateChanges.change), resetStateName)
}).then(function() {
return renderAll(stateChanges.create).then(activateAll)
})
}))
function activateStates(stateNames) {
return stateNames.map(prototypalStateHolder.get).forEach(function(state) {
var context = new EventEmitter()
extend(context, {
domApi: activeDomApis[state.name],
data: state.data,
parameters: parameters,
content: getContentObject(activeStateResolveContent, state.name)
})
activeEmitters[state.name] = function emit() {
context.emit.apply(context, arguments)
}
try {
state.activate(context)
} catch (e) {
console.error(e)
}
})
}).then(function() {
stateProviderEmitter.emit('state change finished')
}).catch(handleError)
}
})).then(function stateChangeComplete() {
current.set(newStateName, parameters)
try {
stateProviderEmitter.emit('stateChangeEnd', newStateName, parameters)
} catch (e) {
handleError('error', e)
}
}).catch(ifNotCancelled(function handleStateChangeError(err) {
if (err && err.redirectTo) {
stateProviderEmitter.emit('stateChangeCancelled', err)
return stateProviderEmitter.go(err.redirectTo.name, err.redirectTo.params, { replace: true })
} else if (err) {
handleError('stateChangeError', err)
}
})).catch(function handleCancellation(err) {
if (err && err.wasCancelledBySomeoneElse) {
// we don't care, the state transition manager has already emitted the stateChangeCancelled for us
} else {
throw new Error("This probably shouldn't happen, maybe file an issue or something " + err)
}
})
}
function getDestinationUrl(stateName, parameters) {
return prototypalStateHolder.guaranteeAllStatesExist(stateName).then(function() {
var route = prototypalStateHolder.buildFullStateRoute(stateName)
return buildPath(route, parameters || {})
})
}
var defaultOptions = {
replace: false
}
stateProviderEmitter.addState = addState
stateProviderEmitter.go = function go(newStateName, parameters, options) {
options = extend({}, defaultOptions, options)
var goFunction = options.replace ? hashRouter.replace : hashRouter.go
return getDestinationUrl(newStateName, parameters).then(goFunction, handleError.bind(null, 'stateChangeError'))
}
return stateProviderEmitter

@@ -131,2 +244,11 @@ }

function redirector(newStateName, parameters) {
return {
redirectTo: {
name: newStateName,
params: parameters
}
}
}
// { [stateName]: resolveResult }

@@ -137,3 +259,16 @@ function resolveStates(states, parameters) {

var resolves = Promise.all(statesWithResolveFunctions.map(function(state) {
return Promise.denodeify(state.resolve)(state.data, parameters)
return new Promise(function (resolve, reject) {
function resolveCb(err, content) {
err ? reject(err) : resolve(content)
}
resolveCb.redirect = function redirect(newStateName, parameters) {
reject(redirector(newStateName, parameters))
}
var res = state.resolve(state.data, parameters, resolveCb)
if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') {
resolve(res)
}
})
}))

@@ -158,2 +293,6 @@

function reverse(ary) {
return ary.slice().reverse()
}
function isFunction(property) {

@@ -164,14 +303,1 @@ return function(obj) {

}
function buildRoute(prototypalStateHolder, stateName) {
return prototypalStateHolder.getHierarchy(stateName).reduce(function(route, state) {
if (route && route[route.length - 1] !== '/' && state.route[0] !== '/') {
route = route + '/'
}
return route + state.route
}, '')
}
function reverse(ary) {
return [].concat(ary)
}
{
"name": "abstract-state-router",
"version": "2.0.0",
"version": "3.0.0",
"description": "The basics of a client-side state router ala the AngularJS ui-router, but without any DOM interactions",

@@ -26,4 +26,5 @@ "main": "index.js",

"combine-arrays": "^1.0.0",
"extend": "^2.0.0",
"hash-brown-router": "^1.3.0",
"path-to-regexp": "^1.0.1",
"page-path-builder": "^1.0.1",
"promise": "^6.0.1",

@@ -33,6 +34,4 @@ "promise-map-series": "^0.2.0"

"devDependencies": {
"extend": "^2.0.0",
"page": "^1.3.7",
"tape": "^2.14.0"
}
}

@@ -7,5 +7,7 @@ To manage webapp states so that you don't have to deal with url paths or anything.

var createStateRouter = require('abstract-state-router')
```js
var createStateRouter = require('abstract-state-router')
var stateRouter = createStateRouter(renderer, rootElement, router)
var stateRouter = createStateRouter(renderer, rootElement, router)
```

@@ -18,3 +20,3 @@ The renderer should be an object with four properties: render, destroy, getChildElement, and reset. Still needs to be documented, see test/support/renderer-mock.js for an implementation.

# stateRouter.addState({name, route, data, template, resolve, activate})
# stateRouter.addState({name, route, defaultChild, data, template, resolve, activate, querystringParameters})

@@ -27,5 +29,7 @@ The addState function takes a single object of options.

`defaultChild` is a string (or a function that returns a string) of the default child's name. If you attempt to go directly to a state that has a default child, you will be directed to the default child. (E.g. if 'contacts' has the defaultChild 'list', then doing `state.go('contacts')` will actually do `state.go('contacts.list')`.)
`data` is an object that can hold whatever you want - it will be passed in to the resolve and callback functions.
`template` is a template string/object/whatever to be interpreted by the render function
`template` is a template string/object/whatever to be interpreted by the render function.

@@ -36,4 +40,6 @@ `resolve` is a function called when the selected state begins to be transitioned to, allowing you to accomplish the same objective as you would with ui-router's [resolve](https://github.com/angular-ui/ui-router/wiki#resolve).

## resolve(data, parameters, callback(err, content), redirectCallback(stateName, params))
`querystringParameters` is an array of query string parameters that will be watched by this state.
## resolve(data, parameters, callback(err, content).redirect(stateName, params))
The first argument is the data object you passed to the addState call. The second argument is an object containing the parameters that were parsed out of the route params and the query string.

@@ -43,12 +49,19 @@

If you call `redirectCallback(stateName, params)`, the state router will begin transitioning to that state instead. The current destination will never become active, and will not show up in the browser history.
If you call `callback.redirect(stateName, params)`, the state router will begin transitioning to that state instead. The current destination will never become active, and will not show up in the browser history.
## activate(domApi, data, parameters, content)
## activate(context)
The activate function is called when the state becomes active. It is passed the DOM API from the rendering function, the data object from the addState call, the route/querystring parameters, and the content object passed into the resolveFunction's callback.
The activate function is called when the state becomes active. It is passed an event emitter named `context` with four properties:
This is the point where you display the view for the current state!
- `domApi`: the DOM API returned by the renderer
- `data`: the data object given to the addState call
- `parameters`: the route/querystring parameters
- `content`: the object passed into the resolveFunction's callback
# stateRouter.go(stateName, parameters, [options])
###events
- 'destroy': emitted when the state is destroyed
# stateRouter.go(stateName, [parameters, [options]])
Browses to the given state, with the current parameters. Changes the url to match.

@@ -58,17 +71,25 @@

If a state change is triggered during a state transition, it is queued and applied once the current state change is done.
# State change flow
- emit StateChangeStarted
- emit StateChangeStart
- call all resolve functions
- resolve functions return
= NO LONGER AT PREVIOUS STATE
- destroy existing dom elements
- call all render functions
- call all controller functions
- **NO LONGER AT PREVIOUS STATE**
- destroy the contexts of all "destroy" and "change" states
- destroy appropriate dom elements
- reset "change"ing dom elements - still needs implemented
- call render functions for "create"ed states
- call all activate functions
- emit StateChangeEnd
# Every state change does this to states
- destroy: states that are no longer active at all. The contexts are destroyed, and the DOM elements are destroyed.
- change: states that remain around, but with different parameter values - the DOM sticks around, but the contexts are destroyed and resolve/activate are called again.
- create: states that weren't active at all before. The DOM elements are rendered, and resolve/activate are called.
# TODO
- "redirect somewhere else instead" function in the resolve
- "redirect somewhere else instead" function during activation
- emitting errors when trying to navigate to an invalid state
- the ability to set an "error" state to go to on errors

@@ -81,1 +102,2 @@

[![Build Status](https://travis-ci.org/TehShrike/abstract-state-router.svg?branch=master)](https://travis-ci.org/TehShrike/abstract-state-router)
var stateStringParser = require('./state-string-parser')
var Promise = require('promise')
var parse = require('./state-string-parser')

@@ -27,4 +29,5 @@ module.exports = function StateState() {

if (names.length > 1) {
names.pop()
return names.join('')
var secondToLast = names.length - 2
return names[secondToLast]
} else {

@@ -35,2 +38,47 @@ return null

function guaranteeAllStatesExist(newStateName) {
return new Promise(function(resolve) {
var stateNames = parse(newStateName)
var statesThatDontExist = stateNames.filter(function(name) {
return !states[name]
})
if (statesThatDontExist.length > 0) {
throw new Error('State ' + statesThatDontExist[statesThatDontExist.length - 1] + ' does not exist')
}
resolve()
})
}
function buildFullStateRoute(stateName) {
return getHierarchy(stateName).reduce(function(route, state) {
if (route && route[route.length - 1] !== '/' && state.route[0] !== '/') {
route = route + '/'
}
return route + (state.route || '')
}, '')
}
function applyDefaultChildStates(stateName) {
var state = states[stateName]
function getDefaultChildStateName() {
return state && (typeof state.defaultChild === 'function'
? state.defaultChild()
: state.defaultChild)
}
var defaultChildStateName = getDefaultChildStateName()
if (!defaultChildStateName) {
return stateName
}
var fullStateName = stateName + '.' + defaultChildStateName
return applyDefaultChildStates(fullStateName)
}
return {

@@ -41,8 +89,11 @@ add: function(name, state) {

get: function(name) {
return states[name]
return name && states[name]
},
getHierarchy: getHierarchy,
getParent: getParent,
getParentName: getParentName
getParentName: getParentName,
guaranteeAllStatesExist: guaranteeAllStatesExist,
buildFullStateRoute: buildFullStateRoute,
applyDefaultChildStates: applyDefaultChildStates
}
}

@@ -203,1 +203,24 @@ var test = require('tape')

})
test('changing from app.main.tab1 to just main', function(t) {
var results = setup()('app.main.tab1', { main1: 'wut' }, 'app', {})
compareAllElements(t, [{
stateNameChanged: false,
stateParametersChanged: false,
nameBefore: 'app',
nameAfter: 'app'
}, {
stateNameChanged: true,
stateParametersChanged: false,
nameBefore: 'app.main',
nameAfter: undefined
}, {
stateNameChanged: true,
stateParametersChanged: false,
nameBefore: 'app.main.tab1',
nameAfter: undefined
}], results)
t.end()
})

@@ -1,57 +0,5 @@

/* Don't forget to test
- calling go with replace=true, and then having that state also call replace, or just error out the state transition
*/
var test = require('tape')
var hashRouterFactory = require('hash-brown-router')
var hashLocationMockFactory = require('hash-brown-router/hash-location-mock')
var stateRouterFactory = require('../')
var mockRenderFn = require('./support/renderer-mock')
var assertingRendererFactory = require('./helpers/asserting-renderer-factory')
var getTestState = require('./helpers/test-state-factory')
function getTestState(t, renderFn) {
var hashRouter = hashRouterFactory(hashLocationMockFactory())
var stateRouter = stateRouterFactory(renderFn || mockRenderFn, 'body', hashRouter)
hashRouter.setDefault(function noop() {})
stateRouter.addState({
name: 'dummy',
route: '/dummy',
data: {},
render: t.fail.bind(t, 'dummy route was called')
})
return {
hashRouter: hashRouter,
stateRouter: stateRouter
}
}
function assertingRenderFunctionFactory(t, expectedTemplates) {
return {
render: function render(element, template, cb) {
t.ok(expectedTemplates.length, 'The render function hasn\'t been called too many times yet')
var expected = expectedTemplates.shift()
t.equal(expected, template, 'The expected template was sent to the render function')
process.nextTick(function() {
cb(null, {
template: template
})
})
},
reset: function reset(renderedTemplateApi, cb) {
setTimeout(cb, 100)
},
destroy: function destroy(renderedTemplateApi, cb) {
setTimeout(cb, 100)
},
getChildElement: function getChildElement(renderedTemplateApi, cb) {
setTimeout(function() {
cb(null, 'dummy child element')
}, 100)
}
}
}
test('normal, error-less state activation flow for two states', function(t) {

@@ -70,9 +18,9 @@ function basicTest(t) {

var state = getTestState(t, assertingRenderFunctionFactory(t, [parentTemplate, childTemplate]))
var renderer = assertingRendererFactory(t, [parentTemplate, childTemplate])
var state = getTestState(t, renderer)
var stateRouter = state.stateRouter
var assertsBelow = 18
var renderAsserts = 4
var renderAsserts = renderer.expectedAssertions
t.plan(assertsBelow + renderAsserts)
console.log('Plan for', assertsBelow + renderAsserts)

@@ -83,3 +31,2 @@ var parentResolveFinished = false

stateRouter.addState({

@@ -99,3 +46,8 @@ name: 'rofl',

querystringParameters: ['wat'],
activate: function(domApi, data, parameters, content) {
activate: function(context) {
var domApi = context.domApi
var data = context.data
var parameters = context.parameters
var content = context.content
t.notOk(parentStateActivated, 'parent state hasn\'t been activated before')

@@ -127,3 +79,8 @@ parentStateActivated = true

},
activate: function(domApi, data, parameters, content) {
activate: function(context) {
var domApi = context.domApi
var data = context.data
var parameters = context.parameters
var content = context.content
t.ok(parentStateActivated, 'Parent state was activated before the child state was')

@@ -157,88 +114,138 @@ t.ok(childResolveFinished, 'Child resolve was completed before the activate')

// test('calls resolve callback, passes results to the render callback', function(t) {
// var state = getTestState(t)
test('undefined data, querystring, and resolve function', function(t) {
function basicTest(t) {
var parentTemplate = {}
// t.plan(3)
var renderer = assertingRendererFactory(t, [parentTemplate])
var state = getTestState(t, renderer)
var assertsBelow = 3
// var resolveData = {}
// var originalData = {}
t.plan(assertsBelow + renderer.expectedAssertions)
// function resolve(data, parameters, cb) {
// t.pass('resolve function called')
// t.equal(parameters.wat, 'wut', 'received the parameter from the url')
// process.nextTick(function() {
// cb(null, resolveData)
// })
// }
state.stateRouter.addState({
name: 'rofl',
route: '/routeButt',
template: parentTemplate,
activate: function(context) {
var data = context.data
var parameters = context.parameters
var content = context.content
// function render(data, parameters, content) {
// t.equal(content, resolveData, 'received the object from the resolve function')
// t.end()
// }
t.equal(typeof data, 'undefined', 'data is undefined')
t.equal(parameters.wat, 'wut', 'got the parameter value')
t.equal(Object.keys(content).length, 0, 'No keys on the content object')
t.end()
}
})
// stateRouter.addState({
// name: 'someRoute',
// route: '/routeButt',
// data: originalData,
// querystringParameters: ['wat'],
// resolve: resolve,
// render: render
// })
return state
}
// state.hashRouter.go('/routeButt?wat=wut')
// })
t.test('triggered with go()', function(t) {
var stateRouter = basicTest(t).stateRouter
stateRouter.go('rofl', { wat: 'wut' })
})
// test('activates both parent and child state', function(t) {
// var state = getTestState(t)
t.test('triggered by the router', function(t) {
var hashRouter = basicTest(t).hashRouter
hashRouter.go('/routeButt?wat=wut')
})
})
// t.plan(12)
test('normal, error-less state activation flow for two states', function(t) {
var parentData = {}
var child1Data = {}
var child2Data = {}
var parentTemplate = {}
var child1Template = {}
var child2Template = {}
var parentResolveContent = {
parentProperty: 'some string'
}
var child1ResolveContent = {
child1Property: 'a different string'
}
var child2ResolveContent = {
child2Property: 'whatever man'
}
// var parentData = {}
// var childData = {}
// var calledResolveFunctionForParent = false
// var calledResolveFunctionForChild = false
var renderer = assertingRendererFactory(t, [parentTemplate, child1Template, child2Template])
var state = getTestState(t, renderer)
var stateRouter = state.stateRouter
var assertsBelow = 11
// var activatedParent = false
// var activatedChild = false
t.plan(assertsBelow + renderer.expectedAssertions)
// state.stateRouter.addState({
// name: 'parent',
// route: '/routeParent',
// data: parentData,
// resolve: function(cb) {
// t.notOk(calledResolveFunctionForParent, 'Called the parent\'s resolve function for the first time')
// t.notOk(activatedParent, 'Called the resolve function before the render function')
// calledResolveFunctionForParent = true
// },
// render: function(data, parameters, content) {
// t.equal(data, parentData, 'got back the parent data object')
// t.notOk(parameters.wat, 'wut', 'got the right parameter')
// t.notOk(activatedParent, 'have not activated the parent before')
// t.notOk(activatedChild, 'have not activated the child yet')
// activatedParent = true
// }
// })
var parentResolveCalled = false
var parentStateActivated = false
var child1ResolveCalled = false
var child1Activated = false
// state.stateRouter.addState({
// name: 'parent.child',
// route: '/routeChild',
// querystringParameters: ['wat'],
// data: childData,
// resolve: function(cb) {
// t.notOk(calledResolveFunctionForChild, 'Called the child\'s resolve function for the first time')
// t.notOk(activatedChild, 'Called the resolve function before the render function')
// calledResolveFunctionForChild = true
// },
// render: function(data, parameters, content) {
// t.equal(data, childData, 'got back the child data object')
// t.equal(parameters.wat, 'wut', 'got the right parameter')
// t.ok(activatedParent, 'have already activated the parent')
// t.notOk(activatedChild, 'have not activated the child before')
// activatedChild = true
// t.end()
// }
// })
stateRouter.addState({
name: 'parent',
route: '/parent',
data: parentData,
template: parentTemplate,
resolve: function(data, parameters, cb) {
t.notOk(parentResolveCalled, 'parent resolve function hasn\'t been called before')
parentResolveCalled = true
setTimeout(function() {
cb(null, parentResolveContent)
}, 50)
},
querystringParameters: ['wat'],
activate: function(context) {
t.notOk(parentStateActivated, 'parent state hasn\'t been activated before')
parentStateActivated = true
}
})
// state.hashRouter.go('/routeParent/routeChild?wat=wut')
// })
stateRouter.addState({
name: 'parent.child1',
route: '/child1',
data: child1Data,
template: child1Template,
resolve: function(data, parameters, cb) {
t.notOk(child1ResolveCalled, 'child1 resolve function hasn\'t been called before')
child1ResolveCalled = true
setTimeout(function() {
cb(null, child1ResolveContent)
}, 50)
},
activate: function(context) {
t.notOk(child1Activated, 'child1 hasn\'t been activated before')
setTimeout(function() {
stateRouter.go('parent.child2', { wat: 'some value' })
})
}
})
stateRouter.addState({
name: 'parent.child2',
route: '/child2',
data: child2Data,
template: child2Template,
resolve: function(data, parameters, cb) {
t.equal(data, child2Data, 'got back the correct child2 data object in the child2 resolve function')
t.equal(parameters.wat, 'some value', 'got the parent\'s querystring value in the child2 resolve function')
setTimeout(function() {
cb(null, child2ResolveContent)
}, 50)
},
activate: function(context) {
t.equal(context.domApi.template, child2Template, 'got back the correct DOM API')
t.equal(context.data, child2Data, 'Got back the correct data object')
t.equal(context.content.parentProperty, parentResolveContent.parentProperty, 'The child2 activate function got the parent property from the resolve function object')
t.equal(context.content.child2Property, child2ResolveContent.child2Property, 'The child2 activate function got the child2 property from the resolve function')
t.equal(context.parameters.wat, 'some value', 'got the the parent\'s parameter value in the child2\'s activate function')
t.end()
}
})
stateRouter.go('parent.child1', { wat: 'some value' })
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc