Angular metadata service [$injector:unpr]
Asked Answered
H

3

0

I'm writing metadata service for my website and SEO optimisaion and it seems i cant get past the error. I'm not sure why. I have my html controller tag inserted in head tag
ng-controller="MetaDataCtrl". I'm beginer in Angular and I'm scraping from on line tutorials.

I found this code in:dynamic metadata in angular

Main.js

    var app = angular.module('WebApp', [
      'ngRoute'
    ]);
      angular.module("WebApp").service("metadataService" ["$location",              "$rootScope", function($location, $routescope) {
     var self = this;
     self.tags = {};

// Set custom options or use provided fallback (default) options
self.loadMetadata = function loadMetadata(metadata) {
   metadata = metadata || {};
   metadata.title = metadata.title || 'BNL Consulting';
   metadata.description = metadata.description || 'We are BNL Consulting.';
   document.title = metadata.title;
   self.tags = metadata;
};

// Make sure data gets reloaded when navigation occurs
$rootScope.$on('$routeChangeSuccess', function (event, newroute, oldroute) {
   self.loadMetadata(newroute.metadata);
});
}
]),

    /**
     * Configure the Routes
     */
    app.config(['$routeProvider', '$locationProvider', function($routes, $location) {
     $location.html5Mode(true).hashPrefix('!');
      $routes
        // Home
        .when("/", {templateUrl: "partials/home.html",  
          controller: "PageCtrl",
          metadata: {
               title: 'This is my title',
               description: 'This is Desc.' }

        })
    }]);

    app.controller('PageCtrl', function (/* $scope, $location, $http */) {

    });

    .controller('MetadataCtrl', function ($scope, metadataService) {
       $scope.meta = metadataService;
    });
Holliehollifield answered 4/11, 2015 at 12:37 Comment(0)
L
1

This is the proper code, as shown in the article you linked (here). I wrote the article, and it worked seamlessly for me. This also includes hardcoded fallback tags in case Javascript isn't picked up by the crawler.

Note: these aren't the complete files, just the important parts of those that are relevant. If you need help writing the boilerplate for directives, services, etc. that can be found elsewhere. Anyway, here goes...

app.js

This is where you provide the custom metadata here for each of your routes (title, description, etc.)

$routeProvider
   .when('/', {
       templateUrl: 'views/homepage.html',
       controller: 'HomepageCtrl',
       metadata: {
           title: 'The Base Page Title',
           description: 'The Base Page Description' }
   })
   .when('/portfolio', {
       templateUrl: 'views/portfolio.html',
       controller: 'PortfolioCtrl',
       metadata: {
           title: 'The Portfolio Page Title',
           description: 'The Portfolio Page Description' }
   })

metadata-service.js (service)

Sets the custom metadata options or use defaults as fallbacks.

var self = this;

// Set custom options or use provided fallback (default) options
self.loadMetadata = function(metadata) {
  self.title = document.title = metadata.title || 'Fallback Title';
  self.description = metadata.description || 'Fallback Description';
  self.url = metadata.url || $location.absUrl();
  self.image = metadata.image || 'fallbackimage.jpg';
  self.ogpType = metadata.ogpType || 'website';
  self.twitterCard = metadata.twitterCard || 'summary_large_image';
  self.twitterSite = metadata.twitterSite || '@fallback_handle';
};

// Route change handler, sets the route's defined metadata
$rootScope.$on('$routeChangeSuccess', function (event, newRoute) {
  self.loadMetadata(newRoute.metadata);
});

metaproperty.js (directive)

Packages the metadata service results for the view.

return {
  restrict: 'A',
  scope: {
    metaproperty: '@'
  },
  link: function postLink(scope, element, attrs) {
    scope.default = element.attr('content');
    scope.metadata = metadataService;

    // Watch for metadata changes and set content
    scope.$watch('metadata', function (newVal, oldVal) {
      setContent(newVal);
    }, true);

    // Set the content attribute with new metadataService value or back to the default
    function setContent(metadata) {
      var content = metadata[scope.metaproperty] || scope.default;
      element.attr('content', content);
    }

    setContent(scope.metadata);
  }
};

index.html

<head>
  <title>Fallback Title</title>
  <meta name="description" metaproperty="description" content="Fallback Description">

  <!-- Open Graph Protocol Tags -->
  <meta property="og:url" content="fallbackurl.com" metaproperty="url">
  <meta property="og:title" content="Fallback Title" metaproperty="title">
  <meta property="og:description" content="Fallback Description" metaproperty="description">
  <meta property="og:type" content="website" metaproperty="ogpType">
  <meta property="og:image" content="fallbackimage.jpg" metaproperty="image">

  <!-- Twitter Card Tags -->
  <meta name="twitter:card" content="summary_large_image" metaproperty="twitterCard">
  <meta name="twitter:title" content="Fallback Title" metaproperty="title">
  <meta name="twitter:description" content="Fallback Description" metaproperty="description">
  <meta name="twitter:site" content="@fallback_handle" metaproperty="twitterSite">
  <meta name="twitter:image:src" content="fallbackimage.jpg" metaproperty="image">
</head>
Luisaluise answered 19/11, 2015 at 17:28 Comment(2)
thank you so much. This is picture perfect. On3 more thing did you use prerender io on your site?Holliehollifield
@user3187715, we have started to use Prerender to achieve fully dynamic metadata across a range of social channels (Facebook, Twitter, LinkedIn, etc.) because their crawlers are still incapable of parsing Javascript. That being said, this answer works for search engines and will give basic coverage for most simple use cases on those popular social networks.Luisaluise
H
0

I believe it's because your tag is on the head tag which seems to be a special case. I believe your question will be answered by this.

Henze answered 4/11, 2015 at 12:53 Comment(1)
I will try it out and report what i find.Holliehollifield
H
0

I solved this problem and i wanna share for other users. I tried this way based on article for SEO optimization but it doesn't work google bots still see {{meta.tags.title }} and not Some dynamic text. I didnt write my services in the right way so the error keep poping when i wrote ng-controller. If you services are working fine tag has no problem with angularJs tags

app.service("metadataService", ['$rootScope', function($rootScope) {
    var self = this;
    self.tags = {};

    // Set custom options or use provided fallback (default) options
    self.loadMetadata = function loadMetadata(metadata) {
        metadata = metadata || {};
        metadata.title = metadata.title || 'Meta Data ';
        metadata.description = metadata.description || 'DESCRIPTION';
        metadata.keywords = metadata.keywords || 'Some, Key, Words' ;
        document.title = metadata.title;
        self.tags = metadata;
    }
    ;

    // Make sure data gets reloaded when navigation occurs
    $rootScope.$on('$routeChangeSuccess', function(event, newroute, oldroute) {
        self.loadMetadata(newroute.metadata);
    }
    );

}
])
Holliehollifield answered 6/11, 2015 at 6:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.