Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS not showing my ng-view

I'm trying to do a simple angular app with rails. For some reason my <div ng-view></div> html tag shows as <!-- ngView: --> when I view the inspector. I'm not getting any errors in the console. I'm new to Angularjs and I can't figure out why this is happening. Below is my code, hopefully I've included everything to give you an idea. I'm using 'angular-rails-templates' gem which allows me to add my html templates within Angular's template cache.

application.html.haml

!!! 5
%html{'ng-app'=>'AD'}
  %head
    = stylesheet_link_tag "application", media: "screen", "data-turbolinks-track" => true
    = javascript_include_tag "application", "angular/discussions_app", "data-turbolinks-track" => true
  %body
   .col-sm-12
     :plain
       <div ng-view></div>

app.js.coffee

#= require_self
#= require_tree ./controllers
#= require_tree ./directives
#= require_tree ./filters
#= require_tree ./services

# Creates new Angular module called 'AD'
@AD = angular.module('AD', ['ngRoute', 'templates'])

# Sets up routing
@AD.config(['$routeProvider', ($routeProvider) ->
  $routeProvider
    .when('/discussion', { templateUrl: 'angular/templates/discussions/index.html', controller: 'DiscussionsIndexCtrl' } )
    .otherwise({ redirectTo: '/discussions' })
])

indexCtrl.js.coffee

@AD.controller 'DiscussionsIndexCtrl', ($scope) ->
   console.log 'hello'

index.html

<h1 class="text-center">Hello World</h1>

Edit 1

I have a rails route which is http://localhost:3000/user/:slug/ and I'd like to use Angular.js on this page with my discussions route so it will end up being http://localhost:3000/user/:slug/#/discussions. What is the correct way of setting up the Angular.js route? It would be good be to store the :slug in my Angular's discussions controller.

like image 660
Peter Avatar asked Apr 18 '26 10:04

Peter


1 Answers

Your code should work for the discussion route.

Two things I would check:

  1. Your otherwise route has a redirectTo: /discussions. This is a blank route, as the only other route you define is /discussion (no s). If you are not navigating to discussion then you will get an empty view.

  2. Double check the javascript code that is generated by your template gem is populating the templateCache for 'angular/templates/discussions/index.html'. I have used something similar which would include the .haml extension. Also confirm that you are loading the templates javascript before the angular app.

  3. If both of the above are correct, can you verify that you're seeing "hello" printed to the console?

Response to EDIT 1

It is important to remember that angular is a single page application (SPA) framework. It deals with one html page. As such, it would be better if the example url of http://localhost:3000/user/:slug/ serves the exact same page (e.g. application.html) as http://localhost:3000/ and http://localhost:3000/anything/else/:id, and that your angular router does the rest.

To do this, I would turn html 5 mode on in the location provider by adding this into your .config() block:

$locationProvider.html5Mode(true)

This will mean that your URLs don't use the # anymore, and so /#/discussions would become /discussions. This will work immediately, but you will notice that if you refresh the page your server will respond with a 404. To fix this you need to make any non-api routes return the same application.html page (NOT a redirect to / though, just return the page). Angular automagically looks at the path and works out the route it should be displaying.

Then, in your routeprovider config, you could specify:

.when('/user/:slug/discussions', 
  { 
    templateUrl: 'angular/templates/discussions/index.html', 
    controller: 'DiscussionsIndexCtrl' 
  } 
)

And you can use $routeParams in your controllers to access the relevant information.

Snippet from the docs:

// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}

P.S When I first made this transition, I had API routes mixed in with normal routes, so whilst /users would return JSON, /login would return an html page. I found it MUCH more clear to put all API routes together under /api, so /users became /api/users. This then makes the task of returning application.html trivial without breaking your API: if it doesn't start with /api then return application.html.

like image 146
Ed_ Avatar answered Apr 20 '26 08:04

Ed_



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!