简体   繁体   中英

MEANJS: Check db for url and route to dynamic Angular state

Context Users can register with a unique URL slug that identifies their page, eg ' http://example.com/slug '.

Current State In my Express.js file, I successfully check my database to see if the slug exists on a user, then redirect the user from ' http://example.com/slug ' to ' http://example.com/#!/slug ' to take advantage of Angular's routing.

With Angular, however, I can't use $http or $location services in my router file (since it's taking place inside module.config...see this Stack Overflow explanation for more details).

Desire Basically what I want to do is route the user to a 'default' view when a valid slug is found, or home if it's not. Any suggestions would be much appreciated.

For reference, my module.config code can be found here (note that the 'default' state I want to use is 'search'):

core.client.routes.js

'use strict';

// Setting up route

    angular.module('core').config(['$stateProvider', '$urlRouterProvider', 
        function($stateProvider, $urlRouterProvider) {

            // Redirect to home when route not found.
            $urlRouterProvider.otherwise('/');

            // Home state routing
            $stateProvider.
            state('home', {
                url: '/',
                templateUrl: 'modules/core/views/home.client.view.html'
            }).
            state('search', {
                url: '/search',
                templateUrl: 'modules/core/views/search.client.view.html'
            });
        }
    ]);

What I would like to do, is something like this...

'use strict';

// Setting up route
angular.module('core').config(['$stateProvider', '$urlRouterProvider', '$http', '$location',
    function($stateProvider, $urlRouterProvider, $http, $location) {

        // Get current slug, assign to json.
        var slug = $location.path();
        var data = {
            link: slug
        };

        // Check db for slug
        $http.post('/my/post/route', data).success( function(response) {
            // Found slug in db
        }).error( function(response) {
            // Route to home
            $location.path('/');
        });

        // Home state routing
        $stateProvider.
        state('home', {
            url: '/',
            templateUrl: 'modules/core/views/home.client.view.html'
        }).
        state('search', {
            // Set URL to slug
            url: '/' + slug,
            templateUrl: 'modules/core/views/search.client.view.html'
        });
    }
]);

To directly answer your question, what you want to do is use the routes "resolve" to check for the dependency and redirect to the appropriate view:

 angular.module('app', ['ui.router','ngMockE2E']) .run(function ($httpBackend) { $httpBackend.whenGET(/api\\/slugs\\/.*/).respond(function (method, url) { return url.match(/good$/) ? [200,{name: 'john doe'}] : [404,'']; }); }) .config(function ($stateProvider) { $stateProvider .state( 'search', { url: '/search?terms=:slug', template: '<h1>Search: {{vm.terms}}</h1>', controllerAs: 'vm', controller: function ($stateParams) { this.terms = $stateParams.slug; } } ) .state( 'slug', { url: '/:slug', template: '<h1>Slug: {{vm.user.name}}</h1>', controllerAs: 'vm', controller: function (user) { this.user = user }, resolve: { user: function ($q, $http, $stateParams, $state) { var defer = $q.defer(); $http.get('http://somewhere.com/api/slugs/' + $stateParams.slug) .success(function (user) { defer.resolve(user); }) .error(function () { defer.reject(); $state.go('search', {slug: $stateParams.slug}); }); return defer.promise; } } } ); }); 
 <div ng-app="app"> <script data-require="angular.js@*" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script> <script data-require="ui-router@*" data-semver="0.2.13" src="//rawgit.com/angular-ui/ui-router/0.2.13/release/angular-ui-router.js"></script> <script data-require="angular-mocks@*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular-mocks.js"></script> <a ui-sref="slug({slug: 'good'})">Matched Route</a> <a ui-sref="slug({slug: 'bad'})">Redirect Route</a> <div ui-view></div> </div> 

But, there are a few things you may want to revisit in your example:

  1. Is there a need to perform this check client side if you are already validating and redirecting server side via express?
  2. You seem to be overloading the / route a bit, if home fails, it redirects to itself
  3. You are grabbing slug from $location on app init, not when the view is routed to which could be post init, you need to grab it when ever you are routing to the view
  4. You may want to consider using a GET request to fetch/read data for this request rather than using a POST which is intended generally for write operations (but thats a different story)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM