Coder Social home page Coder Social logo

tehshrike / abstract-state-router Goto Github PK

View Code? Open in Web Editor NEW
295.0 295.0 26.0 1023 KB

Like ui-router, but without all the Angular. The best way to structure a single-page webapp.

Home Page: http://tehshrike.github.io/state-router-example

JavaScript 99.94% HTML 0.06%
router routing single-page-app spa svelte ui-router

abstract-state-router's People

Contributors

artskydj avatar crissdev avatar daytonlowell avatar dependabot[bot] avatar greenkeeperio-bot avatar gudahtt avatar m59peacemaker avatar mtn-view avatar saibotsivad avatar subpx avatar tehshrike avatar walfie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abstract-state-router's Issues

onActivate and onDestroy events

Even more events that I need!

These should emit right after the activate function is called on a state, and right before the destroy event is fired.

Also I apparently forgot to document all the events with #54 so I should do that now.

Request about state router

Hi,

As a hobbiest i am writing a custom app for myself that i want alot of things to do. Ui router in Angular is fine and all but i want a custom one because i dont like angular and its move to 2.0.

I want to know what your Ui-router comes out of the box off and if you could give me some help in setting this up for my project

  1. for SEO is hash tag actually good and does your state router support good practice for routes
  2. is my attached img file possible with your state router (see attachment for my desired router)
  3. is if possible to pass fucntions /data to a certain view by use of the state router through for example the use of a directive or controller

in the attached image i showed you what in projects what i want to develop see as the most commen thing to do for apps yet i was anable to find it if i was good in JS i would be able to pull it off. Thats why im so dependant on good libraries or framework. I do believe though that if you look at my request it can benefit your state router for helping designers like me who arent coders at heart to build a View

regardless of that hats off on making and contributing so much to the open source community

kind regards

Gavarni
state router request

addState options should be well defined

It's not clear from the documentation which addState() options are required.

As far as I know, these are required: name, template, activate and these are not: route, defaultChild, data, resolve, querystringParameters

This should be documented. (Or fixed if this is not the desired case.)

Should an error be thrown when attempting to add a state without all of the required parameters?

No way for children to depend on route parameters of ancestors

If a parent state has a route with a non-querystring-parameter (e.g. /parent/:importantId), there is no way for child states to indicate that they depend on that parameter. The querystringParameters array is only used to check actual querystring parameters - there's no way for the child to indicate that it needs to reset when importantId changes.

Lazy-loading states

On Twitter, Ryan Grove brought up the need to painlessly lazy-load route modules.

On the surface, this seems like it would be easy to implement. The state's template property could be a promise-returning function that would return the real template object. Exactly how the function would go out and get the template/code would be an implementation detail that would depend on the bundler the consumer was using.

In practice, I don't feel comfortable writing out specs until I know of at least one (probably Webpack) user willing to give some real use case details here so that I could be sure that the solution I've thought of would solve a real problem.

So, if you're some Webpack user (or anyone else with a lazy-load-friendly bundler that you want to use) and you want this feature, let me know here! I'm willing to implement it if the complexity doesn't get out of hand.

Modern JS features

Right now abstract-state-router doesn't require any transforms (beyond CommonJS module resolution) to run in an ES5 environment.

ES2015 spreads and spreads, and at this point I feel like most people using abstract-state-router are probably already transpiling to ES5 if they want to support IE11 or older. Certainly anyone using Webpack is, and anyone using Browserify would continue having no problem, as long as the appropriate transforms were added to the package.json.

What could/should be done during such an upgrade? Things that come to mind are

  1. drop the Promise polyfill
  2. upgrade to new language features like const and arrow functions and object destructuring
  3. change the resolve function to take an arguments object instead of two ordered arguments before the callback (probably should have been that way already)
  4. support promises more explicitly? I'm not sure if anything there's actually anything left to do to make the library fully Promise-friendly

A dot/period(.) in url for a named parameter returns an error

When adding a state that includes a named parameter eg /user/:userId, if the named parameter portion of the url includes a dot (eg. /user/123.345) you get the error Cannot GET <path> (see screenshot)

Route code

stateRouter.addState({
    name: 'app.user',
    route: 'user/:userId',
    template: User,
    resolve: (data, parameters, cb) => {
      const {userId} = parameters;
      cb(undefined, { userId });
    }
  });

Result

Screen Shot 2019-04-17 at 9 12 41 am

Emit events on state create/change/remove

Whenever a state is created, changed (template reset), or destroyed, an event should be fired.

The original state and the domApi should be emitted.

The new events should be documented. We'll need a new documentation section it looks like - stateChangeStart and stateChangeEnd and stateChangeError should be noted too.

Push state routing not working with "defaultChild state with an empty route string"

As per title, I cannot get the following scenario to work.

stateRouter.addState({
    name: "app.foo",
    route: "/foo/",
    template: {},
    defaultChild: "view"
})
stateRouter.addState({
    name: "app.foo.view",
    route: "",
    template: {},
})
stateRouter.addState({
    name: "app.foo.edit",
    route: "edit",
    template: {},
})

When I am on a page that has a link asr.go("app.foo"), the url correctly shows as /foo/, but the browser goes to /foo, and nothing renders. If I manually change the url to /foo/, it renders. I have tried removing the / from app.foo, and tried adding it to app.foo.view too.

The edit state works in all instances. Changing the route for app.foo.view to eg view works too.

I am using svelte-state-renderer with embedded components, but I do no think this is the issue, because your demo implementation handles this scenario successfully (without push state routing). So I think the problem must be in ASR.

Get browserstack tests passing again

Thanks to some help from another dev, browserstack tests report their results much more reliably now. I've updated package.json to use the better versions. a3a62f8

It looks like some tests aren't passing any more, most notably the webpack test that tries to read from disc. We should have some difference between node tests and browser tests so that that test doesn't get loaded.

I'm not sure why some of those other tests aren't passing (I saw one about console.error not being a function in Chrome, which it totally is). It would probably be easier to make sure everything passes with tape-run first.

Why doesn't it scroll to the top when you navigate between states

As phrased by @daytonlowell:

huh, totally annoying thing I just now noticed. If you're on state A and scroll down the page and then go to state B, you won't be taken back to the top when state B loads.

A reasonable question that needs a reasonable answer written down somewhere (I know I've answered it a couple times before in chats, so it really needs to be documented).

There are other general questions like this that I know need answers, so I'm thinking there should be a new markdown file at the root of the repo named "reasonable-questions.md" or something, and a list of questions linking to the answers in that file at the bottom of readme.md.

Default values for route parameters

You should be able to set default parameters that will get applied to the route parameters if you do stateRouter.go('someState') or if a default child state is loaded.

defaultQuerystringParameters may already be applied to route parameters, in which case its name (and the documentation) should be updated.

Proposal to implement empty state

I really need to have fake states in the route just for grouping pages.
Currently, we should implement new state and render page with one uiView tag, it looks too complicated and we should have an extra rending pass. Also, our URL became too long.
How I want, example:
A.B.C.D - /a/b/d
A.B.C.E - /a/b/e
but if we will check state to highlight an item in menu A.B.C will be 'active' for both path. C here is the empty state, just for grouping. For .E and .D uiView tag will be from A.B state.
In this case, we still have one path for one state but now possible to use different levels in URL and in the state.

In vue-router some part of similar problem solved by named-views - https://router.vuejs.org/en/essentials/named-views.html
and other by alias.

State name should be optional to `state.go`

If the first argument to state.go is not a string, then it should behave as if you had passed in the name of the current state.

Discussion point: should the "current state" be the last state that the router started transitioning to, or should it be the last state that was fully loaded?

Put another way, if you call redirect({ someParameter: 'some other option' }) inside a resolve function, should it redirect you to the state that was in the middle of being loaded, or the state before that?

I'm leaning towards the state that you're in the middle of transitioning to, but I'm open to other arguments.

Possible to send actual objects via callback.redirect?

My app is using push state routing. In my resolve functions, I am doing some checks before returning a successful callback. For example, you visit book/50, and I do a check to ensure that book 50 exists, the user has permission, etc. If there is a problem, I am doing a callback.redirect() to an error page, and sending an error object in the parameters. However, the object doesn't make it intact to the error state's resolve function, as it gets turned into a parameter on the query line. Is there a way to pass the actual error object to the error state's resolve function?

Write tests/fix "not found" behavior for evaluateCurrentRoute

Right now evaluateCurrentRoute only checks "is there any route" before sending you to a default state.

It would probably be more correct to check "is the route empty?" and if so, send you to that default state, and if not, emit a notFound event or send you to a 404-not-found page.

Thoughts?

evaluateCurrentRoute does not work with defaultChild

  1. app state has the defaultChild: default-child-state
  2. app state has a template
  3. call stateRouter.evaluateCurrentState('app') on an invalid route
  4. white screen of death
  5. call stateRouter.evaluateCurrentState('app.default-child-state') on an invalid path, and app.default-child-state is loaded

Adding "inherit" option to stateRouter.go

I ran into a case where I wanted ui-router's inherit option on a stateRouter.go call.

The option inherit: true should cause any properties on the current route to be carried over to whatever route you are generating a link to.

Unlike in ui-router, it should default to false.

Non-async resolve results in confusing behavior

I put some test data in the resolve, and forgot to set it as an async function. When I try to load a route, I don't get any error message or anything. It just appears to get stuck.

resolve: () => {
    const thing = {
        test_data: true
    }
    return thing
}

I would have expected it to either work as-is, or to throw an error about a missing .then method.

It is possible for `makePath` to return a url that will not be matched by the router

Discovered by @Vehmloewff

If you have a parent state with a route parent and a default child state that has an empty string as its route, makePath will return a route /parent but the router will only be listening for a route with a trailing slash /parent/.

Should probably start with a unit test asserting that the output of both those functions match each other.

I'm just guessing, but the best fix might be to change page-path-builder (used in makePath only) to not add a trailing slash when there are empty chunks like that.

Or maybe the root issue is with the arguments being passed to makePath

Adding multiple keyed templates for a state

Is the following possible? And if not, how would I go about implementing this? I'm open to putting out a PR but am having trouble understanding the codebase.

addState({
   // everything else
  templates: { // normally just one template
    default: componentFn,
    nav: navComponentFn,
  },
})
<uiView name="nav" />
<uiView />

Server-side rendering

  • ability to load resolve data from a global instead of fetching the data remotely (pull request #49)
  • ability to get the resolve data from a state transition
  • another module to wrap renderers and collect the domApis
  • another module to add click handlers to every hash link in the dom, that could be easily composed with state change success events
  • document all of the above, replacing the "server-side rendering" section in the readme

Pull requests accomplishing any of the above bits should be opened against the server-side-rendering branch.

Ignore parameters that are not used by any state

This is one of my diversions from ui-router behavior that I regret.

Right now, you can pass whatever parameters into stateRouter.go or stateRouter.makePath and they will get put into the url and show up on the parameters object, even if no state depends on them.

I think that if you attempt to create a route, or if you try to navigate to a route, and you use any parameters that are not used by any of the states at the route you're going to, then those parameters should just be dropped and shouldn't show up in the url.

This could be accomplished with only a feature bump if a new option was added to stateRouter initialization, something like allowParametersNotUsedByAnyState or whatever. It could default to true (the current behavior).

Eventually, we could log a deprecation warning when that value was true, and eventually eventually we could flip the default to false.

Any thoughts?

Reloading current route

Is there any way to reload the current route? I know I can just not use event.preventDefault() but that reloads the app as a whole.

Curious bug here - Navigating between the same route does not cause reactivation

Great initiative but i noticed a bug.
I have a route route: '/:entity/new'
When i navigate to /one_entity/new, the associated state is activated and rendered.
Then i navigate to /another_entity/new, the associated state is not reactivated since its the same route.
Hence the view (riot tag in my case) does not get updated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.