Angular + Laravel + UI-Router Issue - angularjs

I am creating a SPA using AngularJS, Laravel, and UI-Router. Within the Laravel routes.php file, I have a single route '/' that loads index.php, which is where all my dependencies are included and where angular gets bootstrapped. As a child of the angular rootscope, I have a div with the "ui-view" attribute. This div is where my Angular templates are loaded using UI-Router.
Within my angular module .config, I have a few UI-Router states setup:
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
// Routes config using ui-router
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home',
{
url: '/home',
templateUrl: 'templates/home.html',
controller: 'HomeController'
})
.state('projects',
{
url: '/projects',
templateUrl: 'templates/projects/index.html',
controller: 'ProjectController'
})
.state('projects.create',
{
url: '/projects/create',
templateUrl: 'templates/projects/create.html',
controller: 'ProjectController'
});
}]);
The issue I am having is that when I load the third state, "projects.create", the browser does not bootstrap angular with my js/app.js main module. It fires off an error: "WARNING: Tried to load angular more than once".
But it works fine when I load the "projects" state. Also, by testing I realized that if I change my "projects.create" state URL to "/createproject", instead of "/projects/create", and this fixed the issue.
I presume that this is a path interference issue when trying to load "js/app.js" and other local dependencies. How would I go about resolving this so the apps dependency URL's are dynamic to UI-Router States?
index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AngularJS App</title>
<!--css-->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"/>
</head>
<body ng-app="scynergyApp">
<div class="container">
<div ui-view>
</div>
</div>
</body>
<!--js-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<!--angular core-->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="/js/angular-sanitize.js"></script>
<script src="/js/underscore.js"></script>
<script src="/js/app.js"></script>
<!--angular controllers-->
<script src="/js/controllers/HomeController.js"></script>
<script src="/js/controllers/ProjectController.js"></script>
</html>
Routes.php
<?php
// =============================================
// HOME PAGE ===================================
// =============================================
Route::get('/', function(){
return View::make('index');
});
// =============================================
// API ROUTES ==================================
// =============================================
Route::group(array('prefix'=>'/api'),function(){
Route::post('login','AuthController#Login');
Route::get('logout','AuthController#Logout');
Route::resource('projects','ProjectsController', array('except' => array('create', 'edit', 'update')));
});
// =============================================
// CATCH ALL ROUTE =============================
// =============================================
// all routes that are not home or api will be redirected to the frontend
// this allows angular to route them
App::missing(function($exception)
{
return View::make('index');
});

Your projects.create state maps to the templates/projects/create.html url.
It seems that you do not have that template available, so it falls into your catch-all App::missing, which renders the whole page again.
When loading the page again, you're also running all of its linked resources again, so you're trying to run angular again. Angular detects this, and barks.
Just make sure you have that template file at the specified URL, and all will be fine.

Related

Integration AngularJS with Ratchet.js

I am trying to build an app with RatchetJS (the mobile framework, not the websocket server, ie. goratchet.com !!) and AngularJS (v1.5.8). My question relates to project organization, routing and page loading.
What should handle routing if i want ratchet transitions to play nicely with angular js routing and controllers ? Here is what i have so far.
index.html
<!DOCTYPE html>
<html lang="en" ng-app="Application">
<head>
<meta charset="utf-8">
<title>MyApplication</title>
<base href="/">
<!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<!-- Makes your prototype chrome-less once bookmarked to your phone's home screen -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- Include the compiled Ratchet CSS -->
<link href="css/ratchet.css" rel="stylesheet">
<!-- <link href="css/ratchet-theme-ios.css" rel="stylesheet"> -->
<!-- <link href="css/ratchet-theme-android.css" rel="stylesheet"> -->
<!-- Include the compiled Ratchet JS -->
<script src="js/ratchet.min.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="app/app.js"></script>
</head>
<body>
<div class="view" ng-view></div>
</body>
</html>
The angular JS app file.
'use strict';
(function() {
var Application = angular.module('Application', ['ngRoute']);
Application.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
controller: 'DefaultController',
templateUrl: 'pages/home.html',
})
.when('/pages/chat.html', {
controller: 'ChatController',
templateUrl: '/pages/chat.html',
})
.otherwise({ redirectUrl: '/' })
;
$locationProvider.html5Mode(true);
}]);
Application.controller('DefaultController', ['$scope', '$route', function($scope, $route) {
$scope.title = "Grettings";
}]);
Application.controller('ChatController', ['$scope', function($scope) {
$scope.title = "Chat view";
}]);
})();
There are also two files in /pages/... folder (home.html and chat.html). The home.html contains a link looking like:
<a data-ignore="push" href="/pages/chat.html">Go to chat</a>
If i use data-ignore="push" the page gets loaded, but by angular (so no ratchet transitions. Without it, of course, the page gets loaded by Ratchet but AngularJS does not catch the route and the controller is never called...
Providing i want to use ratchet for transitions. How should i handle my architecture / routing ?
Ratchet is not meant for transitions or what you are refering to.
It is meant as a WebSocket for PHP the problem that you are having is clientside pageloading, so try adding more information about your angular install.

Can I include 'ui-view' inside and 'ng-view' partial page?

I'm just assigned on a SPA (angularJS) project where view routing is maintained with traditional ngRoute. For now I'm not allowed to move all the routing to state based 'UI.Routing' but they permits me i can use ui routing with the new features i will add to the current codebase.So i was thinking if there is way i can work with ui.routing inside of an ng-routing application.
I'm just doing R&D on a sample app where i've put an ng-view and then inside of a specific view i tried to do ui-view but didn't come out with any positive response yet. So i'm just wondering is it really gonna work or i'm just wasting my time.
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>UI Router with ngRoute</title>
<meta charset="utf-8" />
</head>
<body>
<div ng-view="">
</div>
<!-- Vendor Scripts -->
<script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular-route/angular-route.min.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="app/app.js"></script>
<script src="app/settings/routing.js"></script>
<script src="app/settings/uiRouting.js"></script>
</body>
</html>
enter code here
angular.module('app', [
// Angular modules
'ngRoute',
// Custom modules
// 3rd Party Modules
'ui.router'
]);
enter code here
routeManager.$inject = ['$routeProvider'];
function routeManager($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'app/settings/shell.html'
}).otherwise({
redirectTo: '/home'
});
}
angular
.module('app')
.config(routeManager);
enter code here
routeManager.$inject = ['$stateProvider','$urlRouterProvider'];
function routeManager($stateProvider, $urlRouterProvider) {
$stateProvider
.state('test', {
url: '/test',
template: 'Mashallah'
});
$urlRouterProvider.when('', '/test');
}
angular
.module('app')
.config(routeManager);
Hoping for a positive reply
Thanks

How can I use angularjs ui-router without a server i.e. running it from a folder on my computer?

I want to be able to quickly build an AngularJS application using ui-router without having to set up a server. So that I can send this folder to anyone and the application will still work.
I have tried putting a # infront of the route as adviced here. I have also tried to follow other advice related to the ngroute, but nothing seems to work and since I want to use ui-router rather than ng-route I'm not sure whether the advice is even applicable to my situation.
I have also tried to create a manifest file to store the files offline according to this page.
In firefox it kind of works but for some reason it double up what is on the index.html page. But in chrome which is my preferred browser it doesn't work at all. I get an error about a failed ajax call; why don't the manifest file download all pages straight away?
How should I accomplish building an AngularJS app with ui-router without needing a server?
Here is simple snippet of my code:
index.html
<!DOCTYPE html>
<html lang="en" ng-app="app" manifest="mycache.manifest">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<a ui-sref="home.messages">Messages</a>
<div ui-view></div>
<script type="text/javascript" src="bower_components/angular/angular.js"></script>
<script type="text/javascript" src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="js/routes.js"></script>
<script src="js/main.js"></script>
</body>
</html>
messages.html
<button ng-click="contextCtrl.getAllMessages()">Get Messages</button>
<div ng-repeat="message in contextCtrl.messages">
{{message}}
</div>
routes.js
'use strict';
angular.module('app', ['ui.router']);
//Setting up route
angular.module('app').config(['$stateProvider',
function($stateProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'ContextCtrl',
controllerAs:'contextCtrl'
})
.state('home.messages', {
url: '/messages',
templateUrl: 'messages.html',
controller: 'ContextCtrl',
controllerAs:'contextCtrl'
});
}
]);
main.js
'use strict';
/*jslint latedef:false*/
//Controller declaration
angular.module('app').controller('ContextCtrl', ContextCtrl);
function ContextCtrl() {
var vm = this;
vm.messages = [];
vm.getAllMessages = getAllMessages;
function getAllMessages(){
vm.messages = ['m1', 'm2', 'm3', 'm4'];
};
}
mycache.manifest
CACHE MANIFEST
js/main.js
js/routes.js
messages.html
bower_components/angular-ui-router/release/angular-ui-router.js
bower_components/angular/angular.js

Cannot manually navigate to urls

Whenever I manually enter a url into my browser to a site built with Angular, I get:
'HTTP 404
The resource cannot be found
Requested URL: /register'
The only navigable url is http://localhost:XXXX/index.html, from there I have to navigate around the site with anchor tags.
My config file for Angular looks like this:
app.config(function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
//.hashPrefix('!')
$routeProvider
.when('/', {
templateUrl: '/Client/AngularViews/home.html'
})
.when('/register', {
templateUrl: '/Client/AngularViews/register.html',
controller: 'registerController'
})
.when('/post-register', {
templateUrl: '/Client/AngularViews/postRegister.html',
controller: 'registerController'
})
.otherwise({ templateUrl: 'Client/AngularViews/home.html' });
});
Index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="app">
<head>
<script type="text/javascript" src="Scripts/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="Scripts/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<script type="text/javascript" src="Scripts/mainController.js"></script>
<base href="/" />
</head>
<body>
<div class="container-fluid">
<div ng-view></div>
</div>
Can someone explain to me what I'm doing wrong? I want to be able to manually enter urls into the address bar and navigate to anything other than index.html
According to documentation:
Server side
Using this mode requires URL rewriting on server side,
basically you have to rewrite all your links to entry point of your
application (e.g. index.html). Requiring a tag is also
important for this case, as it allows Angular to differentiate between
the part of the url that is the application base and the path that
should be handeled by the application.
https://docs.angularjs.org/guide/$location
So you need some additional support from server-side: configure your http server to reply with index.html for all url you have in your apps.
I use ASP.Net MVC for server side URL rewriting using controllers. Probably not its intended use but works well

Loading controller js files using require.js

I am learning to implement require.js to load the necessary javascript files. I am able to load java script files using require.js which in replace of <script> tags. Even though I am able to load the js files, the content inside the files are not accessible and getting the error saying 'CarApp module not found'. How would this makes the difference?
My index.html where I load require.js
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
<link rel="stylesheet" href="/vendor/bootstrap-2.3.1/css/bootstrap.css" media="screen">
<link rel="stylesheet" href="/css/style.css" media="screen">
<script src="/vendor/angularjs-1.0.5/angular.min.js"></script>
<script src="/vendor/angularjs-1.0.5/angular-resource.min.js"></script>
<script data-main="/js/main" src="/js/require.js"></script>
<div ng-app="CarApp" class="containr">
<div ng-view>
<!-- partial will go here -->
</div>
</div>
/js/main.js
requirejs.config({
paths: {
controllers: './controllers',
app: './app'
}
});
requirejs(['controllers', 'app'],
function (controller, app) { });
/js/app.js
var CarApp = angular.module('CarApp', ['ngResource'])
CarApp.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {controller: ListCtrl, templateUrl: '/partials/list.html'})
.otherwise({redirectTo: '/'})
$locationProvider.html5Mode(true)
})
After loading the app.js file using require.js, it is not able to access 'CarApp' module inside app.js. why is this happening? How can I access 'CarApp module' through main.js.
Your files loaded with RequireJS are not loaded on the page ready event, the time that Angular tries to bootstrap. That is why the CarApp module is not found.
You should bootstrap Angular manually (ref):
Remove the ng-app directive, replace it with an id:
<div id="mainContainer" class="containr">
Bootstrap manually in main.js:
requirejs(['controllers', 'app'], function(controller, app) {
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('mainContainer'), ['myApp']);
});
});
Also check out angular-require-lazy for some, potentially useful, ideas.

Resources