Play application with AngularJS frontend routing - javascript

Im using a the play framework to create a REST service and i want the front end written in Angularjs to make rest calls etc. I have set up a route provider like this:
angular.module("getAbscencePlans", ["getAbscencePlans.services"]).
config(function ($routeProvider) {
$routeProvider
.when('/plans/:companyId', {templateUrl: '/assets/views/plans.html', controller: StoryListController})
//.when('/plans/new', {templateUrl: '/assets/views/create.html', controller: StoryCreateController})
.when('/plans/plan/:planId', {templateUrl: '/assets/views/detail.html', controller: StoryDetailController});
});
my index page has the correct:
ng-app="getAbscencePlans"
in the html tag at the top. However when i go to http://mywebsite.com/plans/2 for example i get a Action not found error. In my routes file i have specified a static resource for the index page, but i presumed my routeProvider would do the rest. What am i doing wrong :(

Have you generated a a JavaScript router in Play? The Play router can generate JS code to handle routing from any JS client like Angular, Knockout etc and you can then select which routes to expose for JS clients.
To do this, follow the step-by-step instruction on Play's documentation here:
https://www.playframework.com/documentation/2.1.0/ScalaJavascriptRouting

Related

Using Django URLs with AngularJs routeProvider

for a project, I am using Django on the back-end and AngularJs on the front end.
Basically, what I want is to run the Angular app only when the url starts with projectkeeper/.
In other words, lets say my website is example.com. I want the angular app to run for the URLs example.com/projectkeeper/dashboard/, example.com/projectkeeper/projects/ and so on, but not on example.com/about/.
Hope I have made myself clear. Anyway, in order to do this, I am doing the following with my code:
urls.py
urlpatterns = [
url(r'^projectkeeper/$', TemplateView.as_view(template_name='base.html')),
]
In the template base.html, I refer to my angular app obviously. For the angular routing, I have done the following:
myapp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/dashboard/', {
title: 'Dashboard',
controller : 'DashboardController',
templateUrl : 'static/app_partials/projectkeeper/dashboard.html'
})
.otherwise({ redirectTo : '/' });
}]);
So, ideally, what I thought was that going to example.com/projectkeeper/#/dashboard/ would run the DashboardController from my angular app. However, this is not the case, I only get an empty page which means the routing was incorrect.
Any solutions to this? As I said before, I want is to run the Angular app only when the url starts with projectkeeper/.
I think you're pretty close, there is few things to make this works(honestly, this is confusing to understand and I hope I didn't forget anything).
First, your URLs order is important, if you define something before the angular routes they will be rendered first, so use your django app's urls before the angular one.
Then, if you want to make angular know about the sub-path you need to define <base> tag in your header. In your case:
<base href="/projectkeeper/" />
(you can also define projectkeeperit in all of your where functions tho).
For the urls, I would change the regex to: r'^projectkeeper/.*'. Again, should be the last one in your urls list.
You will encounter other issues like the {{ }}, authentication issues, but those will stay for a different answer :)
Try out this ui router for angularJS
https://github.com/angular-ui/ui-router
It will be more helpful on nested views and problem like which you are facing currently.

AngularJS $routeProvider can't load directly to partial

At the minute I'm currently using the $routeProvider to dynamically load sections of the page like so:
$routeProvider
.when('/', {
templateUrl: '/pages/home.html',
controller: 'mainController'
})
.when('/our-business', {
templateUrl: '/pages/our-business.html',
controller: 'businessController',
css: 'css/_business.css'
})
.when('/solutions', {
templateUrl: '/pages/solutions.html',
controller: 'solutionsController'
});
Currently, if I go directly to the index (localhost) and then select 'Our Business' from the navigation menu then Angular handles the location request and the page loads fine, with the URL changing to localhost/our-business. If I then reload, or open this URL directly I get a 404 error - presumably because Apache is trying to open our-business.html which doesn't exist. If I open localhost/#/our-business then the index is loaded and Angular then handles the request. The issue I've got is that this is designed to be a public facing website, so if a user were to copy and paste the URL or share it via email, they'll get a 404 error.
Is there any way to have Apache rewrite URLs to parse them via the index and AngularJS so that we can keep the non-hash style but still have functional URLs?
As said Kailash you can set the locationProvider to html5 mode
$locationProvider.html5Mode(true)
when you bootstrap your angular application.
Then you have to tell your Apache server to send the index.html (entry point of you single page app) for any requested url.
The angular router will then handle the proper route
Nope. Changing the url without the hash reloads the entire page.
The entire point of this $routeProvider is to build single-page app with multiple views.
Basically, having the # in the url is the only way to do that. Changes to a url's hash don't result in a page reload, and allow Angular to load the relevant views.

Makes Angular JS works offline

I am developing a single page application, with help of AngularJS and I'm new to it
I asked the same question before but haven't got any answer so I am rephrasing my question and ask it again
THE QUESTION:
What I need to do is to make my web app enabled to work offline for this purpose the html files which are rendered as view (for example home.html) should be included somehow in the index.html, So when clicking on the some links there should be no need to have access to a html file instead a part of the same page for example a dive will be rendered, what modifications should I make to project to get this done
at the moment I made different html files and use them as templates when rendering views,
the structure of app is like this :
- index.html
- pages
----- home.html
----- profile.html
here is the code for config the routes and controllers and views
var formApp = angular.module('formApp', ['ngRoute']);
formApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'main',
controller : 'mainController'
})
.when('/profile', {
templateUrl : 'profile',
controller : 'profileController'
})
});
And and my main.html file for example is like this :
<div class="jumbotron text-center">
<h1>Main Page</h1>
<p>{{ message }}</p>
</div>
َand somewhere in the index.html I have
<div ng-view>
{{ message }}
</div>
The code works properly and everything is fine at the moment
To make your application work offline, you have to cache every file with the html5 cache manifest. Even the .html files, images, css, everything...
The native "old" caching won't work here, because it still requires to communicate with the server to have the "304 Not Modified" http code.
The manifest removes this step and doesn't even ask the server for the resources.
An example manifest:
CACHE MANIFEST
/angular.js
/index.html
/page/home.html
/page/profile.html
NETWORK:
*
How to include and use cache manifest check: http://www.w3schools.com/html/html5_app_cache.asp
For debugging:
Clearing a app cache under chrome enter url "chrome://appcache-internals/"
EDIT: Due to comment and off the topic
Instead of placing the html code in many own html files, you can include them in index.html like this:
<script type="text/ng-template" id="one.html">
<div>This is first template</div>
</script>
Then your templateURL is "one.html" without subpath.
Check docs: https://docs.angularjs.org/api/ng/directive/script
Hint:
You dont need to place any paths there. During rendering phase, angularjs will store every html file in the $templateCache under it's id placed in those script elements.
This might not be 100% applicable to you. Depending on the solution & or platform you're using... But I've got a prototype application that I'm working on currently, built in Angular and Node.
Although this was also my fist attempt at something like this... EG caching all the pages upfront. This seems to work quite well.
All my pages get converted to a cache friendly format during the build phase. But in my solution, they are still regular html pages.
home.tpl.html
<div class="well home-menu">
HOME
</div>
templates.js
angular.module('templates', ['home.tpl.html']);
angular.module("home.tpl.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("home.tpl.html",
"<div class=\"well home-menu\">\n" +
"HOME\n"+
"</div>");
}]);
controller
angular.module('myApp.home', ['templates'])
.config(function ($stateProvider) {
$stateProvider
.state('app.home', {
url: '/home',
templateUrl: 'home.tpl.html',
controller: 'HomeController'
});
})
.controller('HomeController', function ($scope) {
//do something
});
All this magic courtesy of html2js
grunt.loadNpmTasks('grunt-html2js');
...I do believe its possible to achieve this effect in various other ways that doesn't require grunt. For example manually creating the templates in the js file... but I wouldn't dream of recommending that route, as it could turn into a nightmare quickly

angularjs ng-template separate file no webserver

So I'm trying to create an app that needs no webserver with AngularJS
I'm using <script type="text/ng-template" id="loginView.html" src="views/login.html"></script> tags to use separate templates and keep things clean.
I wire the thing up in:
app.config(function($routeProvider, $locationProvider){
$locationProvider.hashPrefix("!");
$locationProvider.html5Mode(false);
$routeProvider
.when("/", {
templateUrl: "loginView.html",
controller: "LoginCtrl"
})
.when("/main", {
template: "main",
controller:"MainCtrl.html"
})
.otherwise({
redirectTo: "/"
});
});
My files are not loading. If I put context inside the script tag I can see it.
I have an ng-view to contains the views. But I can't seem to get content from separate files. No errors are given.
Is this possible without a webserver?
Try using <div ng-view /> instead of your script. You can fetch the template just from your file system, you don't need to be on a web server.
Where are you putting those script tags? In the HTML? I don't even know that a script tag like that will do what you expect it to, angular or otherwise, but it isn't necessary. The call you make to $routeProvider.when is sufficient to load the HTML templates. You WILL have to reverse the parameters for your /main route though, as you seem to have the template/templateUrl and controller reversed. Use templateUrl there though. template is for raw HTML.

Angularjs in rails: Change page without reloading?

What is the best practice of changing pages in rails by using angularjs such that there will be no refresh? (I will use fadein animation on the switched page).
In addition to that, If I want to keep database query logic within Angularjs, so is there a way to read Rails url argument (foo.com/:arg) for Angularjs?
If you're working with an existing Rails application which you want to convert to Angular, you'll likely not get to keep a lot of the templating/view code from Rails. Instead, start clean by keeping your server-side APIs and statically serve up your Angular application. If you're starting with a clean rails app, keep in mind that it will basically be Rails' job to provide a JSON/XML API and to statically serve up the Angular app.
To change views in Angular without reloading the page, you'll want to use $routeProvider in coordination with ng-view. Register each of the routes in your application with their corresponding view template:
angular.module('user-manager', [])
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html'
})
.when('/user/:id', {
templateUrl: 'views/user.html',
controller: 'UserCtrl'
})
.otherwise({
redirectTo: '/'
});
});
And then declare the ng-view somewhere in your main index.html:
<body ng-app="user-manager">
<!-- Main view -->
<div ng-view></div>
</body>
The ng-view will get replaced with the relevant template from your routes. For more details and a more complete example, see: http://docs.angularjs.org/api/ngRoute.$route

Categories

Resources