I have a working copy of an Angular app backed by a Rails app.
I put the Angular templates inside app/assets/templates/devices/ and when I need to use a template, I do it like this:
when("/devices", {templateUrl: "assets/devices/select.html", controller: "DevicesListCtrl"})
This works fine in my local machine, but when uploading to Heroku, I get the following error:
Failed to load resource: the server responded with a status of 404 (Not Found)
Any thoughts on how should I approach this?
I have also tried using the following:
//= depend_on_asset devices/index.html
//= depend_on_asset devices/show.html
//= depend_on_asset devices/select.html
window.App = angular.module('TestApp', ['ngResource', 'ngRoute']);
App.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when("/devices", {templateUrl: "<%= asset_path('assets/devices/index.html') %>", controller: "DevicesListCtrl"}).
when("/devices/:id", {templateUrl: "<%= asset_path('assets/devices/show.html') %>", controller: "DevicesShowCtrl"}).
when("/", {templateUrl: "<%= asset_path('assets/devices/select.html') %>", controller: "DevicesSelectCtrl"}).
otherwise({redirectTo: '/devices'});
}]);
But I still get a 404...
I believe that you shouldn't add 'assets' in the URL.
Just do this:
asset_path('devices/index.html');
Related
I am using the raty jquery library, and my images are broken only in production. This is what I've got in my view:
$(document).ready(function(){
$('#target-<%=w_index%>').raty({
half: true,
score: <%= #tastee.try(:jop_rank) || 0 %>,
starOn: <%= image_path('star-on.png') %>,
starOff: '<%= image_path('star-off.png') %>',
starHalf: '<%= image_path('star-half.png') %>',
cancelOn: '<%= image_path('cancel-on.png') %>',
cancelOff: '<%= image_path('cancel-off.png') %>'
});
and the rendered result is that the script has the correct url path and hash:
starOff: '/assets/star-off-6aaeebdaab93d594c005d366ce0d94fba02e7a07fd03557dbee8482f04a91c22.png'
but the rendered image tag has the assets prefix doubled:
<img alt="5" src="/assets//assets/star-off-6aaeebdaab93d594c005d366ce0d94fba02e7a07fd03557dbee8482f04a91c22.png" title="gorgeous">
What might be causing this?
I had previously installed and then removed the ratyrate gem.
I removed it from my gem file and from application.js.erb, however the js file was still in present my assets and compiling due to //= require_tree.
Removed the js file, precompiled and redeployed to solve.
I am using AngularJS and Rails, and followed http://start.jcolemorrison.com/setting-up-an-angularjs-and-rails-4-1-project/ and several other tutorials to get a very simple "Hello World" example up and running on my desktop. The problem is, when I deploy it to a server, none of my code based on Angular works anymore. Instead, I get a Uncaught ReferenceError: require is not defined error in my console.
I realized that part of my problem is that the browser doesn't know what to do with the 'require' function calls, which makes sense so I installed Browserify using browserify-rails. However, it still does not work on the server like I would expect and I get the same error.
Link to the live site: Link
Here's my application.html.erb (simplified):
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>ShibaInu</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => false %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => false %>
<%= csrf_meta_tags %>
</head>
<body ng-app="shibaInu">
<div class="container">1 + 2 = {{ 1 + 2 }}</div>
<div class="container">
<%= yield %>
</div>
</body>
</html>
index.html.erb:
<div ng-view=""></div>
home.html.erb (rendered inside the container):
<h1>The Home View!</h1>
<ul>
<li ng-repeat="thing in things">
{{thing}}
</li>
</ul>
home.js:
angular.module('shibaInu')
.controller('HomeCtrl', function ($scope) {
$scope.things = ['Angular', 'Rails 4.1', 'Working', 'Together!!'];
});
app.js:
angular
.module('shibaInu', [
'ngRoute',
'templates'
]).config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'HomeCtrl'
});
$locationProvider.html5Mode(true);
});
application.js
//= require jquery
//= require jquery_ujs
//= require angular
//= require angular-route
//= require angular-resource
//= require angular-rails-templates
//= require bootstrap-sprockets
//= require ng-app/app.js
//= require_tree ../templates
//= require_tree .
I was doing several things wrong, but I'll try to summarize:
I am minifying JS on my server deployment like a good boy, but I was not writing minification-safe JS. See below for my fixed JS.
This wasn't specified in my original post, but I was not using the angularjs-rails gem like I thought I was. I added this to my project.
Related to 2 above, in my initial post I had used bower to install angularjs like the documentation recommends. For my solution, I took this out because it was just making things messy for my purposes.
New home.js:
angular.module('shibaInu')
.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.things = ['Angular', 'Rails 4.1', 'Working', 'Together!!'];
}]);
New app.js:
angular
.module('shibaInu', [
'ngRoute',
'templates'
]).config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'HomeCtrl'
});
$locationProvider.html5Mode(true);
}]);
I'm following along with the Angular/Rails tutorial at Thinkster and I've run into an issue which seems to be most likely be Angular-related. Everything works just fine until I get to the Angular Routing section. Simply put, the inline templates within the <script> tags do not load in the <ui-view></ui-view> element. I originally thought this may be due to having opened the page locally as a file rather than having it loaded from a server, but the same problem persists even after integrating Rails (using an older version of Sprockets, as pointed out in this similar but unrelated issue).
When I load the index page in either the browser as a file or as a URL when running the Rails server, I've inspected the HTML and, sure enough, the only thing it shows in the code are the divs and an empty <ui-view> element, indicating something just isn't adding up correctly. I've tried various things, including:
Using the newest version of ui-router (0.2.15 at this writing) rather than the version in the tutorial
Using <div ui-view></div> instead of <ui-view></ui-view>
Changing the value of 'url' in the home state to 'index.html', including using the full path to the file (file:///...)
Putting the contents of the inline <script> templates into their own files (without the <script> tags, of course) and specifying the 'templateUrl' field using both relative and full paths
Trying both Chrome and Firefox just to be extra certain
None of these things have worked, even when accessing http://localhost:3000/#/home when the Rails server is running after having integrated Angular into the asset pipeline in the Integrating the Front-end with the Asset Pipeline section of the tutorial. Indeed, the route loads but does not show anything more than a completely blank page with a lonesome and empty <ui-view> element when inspecting the HTML using Chrome's dev tools.
Given that the issue seems to occur even before the Rails portion, it does seem like something to do with Angular itself, but I've got no clue what's going on, especially since I've followed along to the letter.
I'm using Bower to manage the Angular dependencies and the HTML does show that the Angular javascript files in both the app/assets/javascripts directory and in the vendor/assets/bower_components directory are being loaded properly in the <head> section, so everything seems to be okay on the asset pipeline integration.
Versios I'm using:
Rails: 4.2.3
Ruby: 2.2.1p85
Angular: 1.4.3
ui-router: 0.2.15
The code I've got for the major moving parts is below:
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Test App</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
</head>
<body ng-app="testApp">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
app/assets/javascripts/app.js
angular.module('testApp', ['ui.router', 'templates']).config(['$stateProvider', '$urlRouteProvider', function($stateProvider, $urlRouteProvider) {
$stateProvider
.state('home', {
'url': '/home',
'templateUrl': 'home/_home.html',
'controller': 'MainCtrl'
})
.state('posts', {
'url': '/posts/{id}',
'templateUrl': 'posts/_posts.html',
'controller': 'PostsCtrl'
});
$urlRouteProvider.otherwise('home');
}]);
app/assets/javascripts/application.js
//= require angular
//= require angular-rails-templates
//= require angular-ui-router
//= require_tree .
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
respond_to :json
def angular
render 'layouts/application'
end
end
config/routes.rb
Rails.application.routes.draw do
root to: 'application#angular'
end
app/assets/javascripts/home/mainCtrl.js
angular.module('testApp').controller('MainCtrl', ['$scope', 'posts', function($scope, posts) {
$scope.posts = posts.posts;
$scope.addPost = function() {
if (!$scope.title || $scope.title === "")
return;
$scope.posts.push({
'title': $scope.title,
'link': $scope.link,
'upvotes': 0,
'comments': [
{'author': 'Some Person', 'body': 'This is a comment.', 'upvotes': 0},
{'author': 'Another Person', 'body': 'This is also a comment.', 'upvotes': 0}
]
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementUpvotes = function(post) {
post.upvotes++;
};
}]);
app/assets/javascripts/posts/postsCtrl.js
angular.module('testApp').controller('PostsCtrl', ['$scope', '$stateParams', 'posts', function($scope, $stateParams, posts) {
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function() {
if($scope.body === '')
return;
$scope.post.comments.push({
'body': $scope.body,
'author': 'user',
'upvotes': 0
});
$scope.body = '';
};
}]);
app/assets/javascripts/posts/posts.js
angular.module('testApp').factory('posts', ['$http', function($http) {
var o = {
'posts': []
};
o.getAll = function() {
return $http.get('/posts.json').success(function(data) {
angular.copy(data, o.posts);
});
};
return o;
}]);
If any other code is required to help uncover the problem, please let me know and I'll supply anything requested.
it seems that the angular-ui-router is incompatible with the new Rails sprockets. To fix this, add this earlier version of sprockets to your gemfile:
gem 'sprockets', '2.12.3'
And then run bundle update sprockets.
This was answered a few times in other similar questions, like the one below:
Angular Rails Templates just not working
$urlRouteProvider in my code should've been $urlRouterProvider. Be sure to double-check everything, folks, and make good use of the console!
I'm working on integrating AngularJS with Rails and I'm getting some errors that's driving me nuts. I have a AngularJS factory and a controller that's making a call to the index method of a Rails controller, however, I'm getting this error back in the JavaScript console.
Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an array but got an object
http://errors.angularjs.org/1.2.22/$resource/badcfg?p0=array&p1=object
at http://localhost:3000/assets/angular.js?body=1:79:12
at $http.then.value.$resolved (http://localhost:3000/assets/angular-resource.js?body=1:541:23)
at wrappedCallback (http://localhost:3000/assets/angular.js?body=1:11547:81)
at wrappedCallback (http://localhost:3000/assets/angular.js?body=1:11547:81)
at http://localhost:3000/assets/angular.js?body=1:11633:26
at Scope.$eval (http://localhost:3000/assets/angular.js?body=1:12659:28)
at Scope.$digest (http://localhost:3000/assets/angular.js?body=1:12471:31)
at Scope.$apply (http://localhost:3000/assets/angular.js?body=1:12763:24)
at done (http://localhost:3000/assets/angular.js?body=1:8358:45)
at completeRequest (http://localhost:3000/assets/angular.js?body=1:8572:7)
My code is like this:
application.js
//= require jquery
//= require jquery_ujs
//= require angular
//= require angular-resource
//= require bootstrap
//= require jquery.raty
//= require welcome
//= require users
//= require angular/config
//= require angular/factories
//= require_tree ./angular/controllers
config.js
var app = angular.module('sideSkillz', ['ngResource'])
factories.js
var app = window.app;
app.factory('Skillzer', function ($resource) {
return $resource('/skillzers/:id',
{ id: "#id" },
{ update: { method: 'PUT' } }
);
});
skillzersCtrl.js
function skillzersCtrl ($scope, Skillzer) {
$scope.skillzers = Skillzer.query();
}
skillzers_controller.rb
class SkillzersController < ApplicationController
respond_to :html, :json
before_action :find_skillzer, only: :show
def index
#skillzers = Skillzer.all
respond_with #skillzers
end
def show
respond_with #skillzer
end
private
def find_skillzer
#skillzer = Skillzer.find(params[:id])
end
end
skillzers/index.html.haml
.container{ ng: { controller: 'skillzersCtrl' } }
%p{ ng: { repeat: 'skillzer in skillzers' } }
{{skillzer[0].first_name}}
This post has been quite long already with all the code, but this is driving me nuts right now. Also, I understand that it isn't the most efficient code, since it loads the html, and angularjs needs to make another api call, but I'm really using this as a learning exercise for angularjs. Can anyone pinpoint what I'm doing wrong? The examples seem pretty similar to many sample apps (especially Railscasts AngularJS one), but it doesn't work!
Thank you!
Your factory configure for single record. That's why you are getting this error. Below factory for index action.
factories.js
var app = angular.module('sideSkillz');
app.factory('Skillzer', function ($resource) {
return $resource('/skillzers',
{ }, // Query parameters
{ 'query': { method: 'GET' } }
);
});
Hi I followed a tutorial: http://omarriott.com/aux/angularjs-html5-routing-rails/
Here's my manual.js.coffee.erb
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
#= require_tree ./templates
#Bento = angular.module('bento', ['ngRoute', 'ngResource', 'ngSanitize', 'ui.bootstrap', 'infinite-scroll'])
# Pre-cache templates
Bento.run ($window, $templateCache) ->
templates = $window.JST
for fileName of templates
fileContent = templates[fileName]
$templateCache.put(fileName, fileContent)
# Note that we're passing the function fileContent,
# and not the object returned by its invocation.
#= require_tree ./controllers
#= require_tree ./services
#= require_tree ./directives
My routes.js.coffee.erb
#Bento.config ["$routeProvider", ($routeProvider) ->
$routeProvider.when("/",
controller: "ActivitiesController"
templateUrl: "<%= asset_path('templates/user/activities.html.haml') %>"
redirectTo: (current, path, search) ->
if search.goto
"/" + search.goto
else
"/"
).when("/projects/activities",
controller: "ProjectAllActivitiesController"
templateUrl: "<%= asset_path('templates/projects/activities.html') %>"
redirectTo: "/example"
).when("/projects/:id",
controller: "ProjectCtrl"
templateUrl: "<%= asset_path('templates/projects/list.html') %>"
redirectTo: (current, path, search) ->
if search.goto
"/projects/:id" + search.goto
else
"/projects/:id"
).otherwise redirectTo: "/"
]
And lines that I added to my config/routes.rb file
match "api" => proc { [404, {}, ['Invalid API endpoint']] }, via: [:post]
match "api/*path" => proc { [404, {}, ['Invalid API endpoint']] }, via: [:post]
match "/*path" => redirect("/?goto=%{path}"), via: [:post]
Since I'm using rails 4, I need to add a via
# sign is adding whenever I refresh my root path localhost:3000/ but it's not working in nested URLs like localhost:3000/projects/1 it's still reading my routes for RAILS.
PS: Whenever i refresh localhost:3000/projects/activities for example, it's still reading my rails routes instead of going to localhost:3000/example.