Upgrading 2.3's can/control/route

From this gitter thread

@tracer99 asked how to upgrade code like this:

   '/:service route': function(urlContext) {
                this.login(urlContext);
                if (urlContext.service == 'logout') {
                    route.attr({}, true);
                }
            },

Here are my quick suggestions:

Try bringing back can-control-route

I’d create a local copy of https://github.com/canjs/canjs/blob/2.3-legacy/control/route/route.js in your project, but with updated imports.

It seems like processors still exist in 3.0: https://github.com/canjs/can-control/blob/v3.2.4/can-control.js

It’s likely this will fix your problem.

If this does work, let me know. We actually created a https://github.com/canjs/can-control-route, but it seems this was de-prioritized. I’d happily publish it for 3.X and 4.X/5.X.

I actually think this will work for 5.X

Migrate to a more modern approach

A 1:1 mimic of the following:

'/:service route': function(urlContext) {
                this.login(urlContext);
                if (urlContext.service == 'logout') {
                    route.attr({}, true);
                }
},

might look like:

// somewhere
route.regsiter("/{service}");

// in the VM
connectedCallback(){
  this.listenTo(route.urlData, function(ev, url){
    if( route.rule(url ) === "/{service}") {
                var urlContext = route.data.attr() //-> attr if a can-map
                this.login(urlContext);
                if (urlContext.service == 'logout') {
                    route.attr({}, true);
                }
    }
  })
}

You could build something to make this more simple probably …

import {value} from "can";
function routeDataOnRule(rule){
  route.register(rule);
  value.resolvedBy(function( {listenTo} ){
    this.listenTo(route.urlData, function(ev, url){
      if( route.rule(url ) === rule {
                resolve( canReflect.serialize( route.data)  );
      }
    })
  })
}


// in the VM
connectedCallback(){
  this.listenTo( routeDataOnRule("/{service}") , function(urlContext){
                this.login(urlContext);
                if (urlContext.service == 'logout') {
                    route.attr({}, true);
                }
  })
}
1 Like

Hello, when I try to use the can-control-route method, every time I try to load the application, it will crash and produce this error:

Error: Syntax error, unrecognized expression: /:service
at Function.Sizzle.error (jquery.js:1543)
at Sizzle.tokenize (jquery.js:2195)
at Sizzle.compile (jquery.js:2589)
at Sizzle.select (jquery.js:2679)
at Sizzle (jquery.js:847)
at Function.Sizzle.matchesSelector (jquery.js:1506)
at Object.add (jquery.js:4975)
at HTMLDivElement.eval (jquery.js:4941)
at Function.each (jquery.js:356)
at jQuery.fn.init.each (jquery.js:191)

It doesn’t look like can-control-route is loaded, or at least mixed its processor into can-control correctly. This is for a 3.0 app?

This is for an app that i’m trying to upgrade from 2 to 3.
I had created a local copy of the can-control-route, and imported it using steal syntax. I converted all the “can.route()” to use the imported property which was just “route()”. Would there by anything else I would need to do?

it seems like the processor isn’t working … you’ll have to figure out why.

Is this code never being run: https://github.com/canjs/canjs/blob/2.3-legacy/control/route/route.js#L7 ?

I found a way to get past the syntax error I posted before, and also managed to get the processor to run. However when I perform a route change event, the ‘/:service route’ functions never run.

What was your solution for the syntax error and processor? What does your code look like?

It wasn’t a solution, I commented out the code that was causing the “/:service” error. It was on our login router.js code. We have another router.js file for the main application which the can-control-route processor began to work once loaded.

The code would fail in the login router.js page.
This is what the code looked like:

steal(
'src/can-legacy/can-control-route.js',
'can/control/control.js',
'src/util',
'can',
'src/login',
'src/reload',
function (route, Control, APP, can) {
    APP.Login.Router = Control.extend({
        init: function (element, options) {
            //lots of code that we use to init the login page

            route.start();
        },
        'login': function (urlContext) {
            this.destroyControl();
            this.activeController = new APP.Login.Control('#login', {});
        },
        'route': function (urlContext) {
            this.login(urlContext);
        },
        '/:service route': function (urlContext) { //code would fail here with the syntax error
            this.login(urlContext);
            if (urlContext.service == "logout") {
                can.route.attr({}, true);
            }
        },

        //...more route functions...

        'destroyControl': function () {
            //code to destroy controller
        }
    });
    return APP.Login.Router;
}

);

If I comment out the functions after route function, I don’t get the syntax error and the application is able to move onto the next part where it then loads the main application router.js file.

The main application route.js file is a lot larger but similarly organized like the example above. In the canjs 2 version of the application, those route functions will run when an event for them was detected. However with canjs 3 version that does not seem to be happening.