Search code examples
angularjsngrouterouteparams

AngularJS fetching single post by slug with $routeParams fails


I am working on a small AngularJS blogging app (the framework version I use is 1.7.8).

I have managed to pull and display posts from an API I made myself.

I have a problem displaying a single post and I can't figure out its cause.

My app.js file:

angular.module('app', [
    'ngRoute',
    'app.controllers',
    'ngSanitize'
]).config(['$routeProvider', function($routeProvider){
    $routeProvider.when('/', {
        templateUrl: 'templates/posts.html',
        controller: 'PostsController'
    }).when('/:slug', {
        templateUrl: 'templates/singlepost.html',
        controller: 'SinglePostController'
    }).when('/page/:id', {
        templateUrl: 'templates/page.html',
        controller: 'PageController'
    }).otherwise({
        redirectTo: '/'
    });
}]);

Of my two controllers, only the first works as desired:

// All posts
.controller('PostsController', ['$scope', '$http', function($scope, $http){
    $http.get('api').then(function(response) {

        //Categories
        $scope.categories = response.data.categories;

        // Posts
        $scope.posts = response.data.posts;

        // Pages
        $scope.pages = response.data.pages;

    });
}])

// Single post
.controller('SinglePostController', ['$scope', '$http', '$routeParams', function($scope, $http, $routeParams){
    $http.get('api/{slug}').then(function(response) {

        const slug = $routeParams.slug;
        console.log(slug); //consoles the slug post
        console.log(response.data.post); //consoles null

    });
}])

Tthe SinglePostController displays post: null in the console. That puzzles me, especially since:

  1. console.log(slug); shows any posts slug in the console;
  2. replaceing {slug} with an actual slug ("the-future-of-oil", for instance), does display a single posts data in the console.

Where is my mistake?


Solution

  • I have solved the problem by replacing $http.get('api/{slug}') with $http.get('api/' + slug).

    Now, in the controller I have:

    // Single post
    .controller('SinglePostController', ['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) {
        const slug = $routeParams.slug;
        $http.get('api/' + slug).then(function(response) {
    
            //Send single post to the view
            $scope.post = response.data.post;
    
        });
    }])
    

    In the view I have:

    <div class="content">
        <h1>{{post.title}}</h1>
        <div class="meta">Published on {{{post.created_at}}  by {{post.first_name}} {{post.last_name}}</div>
        <div class="post-content">{{post.content}}</div>
    </div>  
    

    It works.