Laravel + Angular - Page not loading - javascript

Im starting to build a new app with laravel and decided to try out angular.js as well.
So I will be using a hybrid approach where the login is made outside angular and then i have a main page where I wanna load the templates using angular.
I got stuck in the loading views part with angular. No errors are shown in the console and the template is not loading as well.
This is my routes.php file:
// Login routes here
...
// Routes protected by auth filter
Route::group(['prefix' => 'admin', 'before' => 'auth'], function(){
Route::get('/', 'AdminPagesController#main'); // Main Page
Route::resource('documents', 'DocumentsController');
});
app/views/admin/layouts/master.blade.php file:
<html ng-app="intern">
<head>
...
</head>
<body>
<div ng-view=""></div>
{{ HTML::script('js/vendor/angular.min.js') }}
{{ HTML::script('js/vendor/angular-route.min.js') }}
{{ HTML::script('js/admin/app.js') }}
{{ HTML::script('js/admin/controllers/documentsController.js') }}
</body>
</html>
public/js/admin/app.js
'use strict';
var intern = angular.module('intern', ['ngRoute'], function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
intern.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/admin', {
templateUrl : 'app/views/admin/documents/index.php',
controller : 'documentsController'
});
$routeProvider.otherwise({templateUrl:'app/views/admin/documents/index.php'});
});
public/js/admin/controllers/documentsController.js (which don't have anything much for now)
intern.controller('documentsController', ['$scope', function(scope){
}]);
and finally my template:
app/views/admin/documents/index.php
<div>
<h1>index documents</h1>
</div>
what am I doing wrong? If you guys need more information please tell me.
Thanks in advance :)

You have to place your templaes into the public folder since the app-folder is not accessible via request from the browser. Alternatively you can write a route for the templates (which is not recommended in my opinion)
Anyway you should see an error in your network-console (404) cause the template cant be loaded

Related

Multiple master page angularjs

I'm starting a new project and am going to be using angularjs.
The page structure is the follow:
/views
loginView.html
mainView.html
loginMaster.html
mainMaster.html
My problem is set the other master page(mainMater.html) after the login.
The routing function is follow:
mainapp.config(['$routeProvider',function($routeProvider) {
$routeProvider.when('/login', {
controller : 'loginController',
templateUrl : '/views/loginView.html'
}).when('/', {
controller : 'mainController',
templateUrl : '/views/mainView.html'
}).otherwise({
redirectTo : '/login'
});
}]);
AngularJS is great for single page applications, which means if you exit the context of javascript by loading an entirely new page, you'll have to setup the context again. I would recommend you to have just one master page (load the page from the server once and perhaps have something like:)
<html ng-app="myApp">
...
<body>
<div class="container" ng-view>
and keep changing the entire view within the ng-view context. Have the login screen, signed in experience, all of it in the same place.

Angularjs: How To Call Controller Function After Routing

I'm learning angularjs and there is one aspect of it that I'm struggling to understand.
My desired/expected behavior of the code below is:
User clicks the Paris link (anchor tag)
The routeProvider intercepts the request, loads the paris.html page into the ng-view.
The 'getCity' function in the controller gets the data and sets the scope variables, which are displayed in the london.html expressions.
However, I can't figure out how to config angularjs to use the 'getCity' function when the html page is loaded into the ng-view. The closest I can get is calling the 'getCity' function from within the CityController itself, bit this seems to have the undesired effect of calling the function when the whole app (index.html) is loaded instead of only when the link is clicked. The controller will have a number of different functions.
I also know you can use ng-click to call a controller's function, but I'm unsure how this would work with loading a html page into an ng-view through the route provider.
Any help would be appreciated. Please see code below from a small app built for learning purposes:
index.html
<!DOCTYPE html>
<html ng-app="mainApp">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-route.js"></script>
</head>
<body>
<ol>
<li>Paris</li>
</ol>
<div class="content-wrapper" ng-controller="CityController">
<div ng-view></div>
</div>
<script src="resources/js/app.js"></script>
<script src="resources/js/CityController.js"></script>
</body>
</html>
app.js
var app = angular.module("mainApp", [ 'ngRoute' ]);
app.config([ '$routeProvider', function($routeProvider) {
$routeProvider.
when('/cities/paris', {
templateUrl : 'resources/paris.html',
controller : 'CityController'
}).
otherwise({
redirectTo : ''
});
} ]);
CityController.js
app.controller('CityController', function($scope, $http) {
$scope.getCity = function() {
$http.get('city')
.success(function(response) {
$scope.name = response.name;
$scope.country = response.country;
}).error(function() {
//Output error to console
});
};
//$scope.getCity();
});
I don't want to call getCity here because it means the http get request to
the 'city' endpoint is called when index.html is loaded
paris.html
This is Paris.
<br><br><br>
Name: {{name}}<br>
Country: {{country}}
<br><br><br>
I think what you are looking for is the router resolve option.
A resolve contains one or more promises that must resolve successfully before the route will change. This means you can wait for data to become available before showing a view, and simplify the initialization of the model inside a controller because the initial data is given to the controller instead of the controller needing to go out and fetch the data.
Check the explanation and usage here
You can call getCity() from paris.html using ,ng-init=getCity() ,ng-init will call your function as soon as paris.html is loaded into your ng-view .
For Eg.
This is Paris.
<br><br><br>
<div ng-init=getCity() >
Name: {{name}}<br>
Country: {{country}}
</div>
<br><br><br>

Login Page without Index.html Design - ngRoute (AngularJS)

I'm using ngRoute to do the routing of my AngularJS application (myApp) but I have a problem: I don't know how to NOT APPLY my index.html design (with all my sidebars) to my login.html page, which seems to be applied by default if it is defined as a view. I want a simple design for my login.html page: only two fields to fill out, without the design of my index.html, which is applied to all the views in myApp. Thereby, I don't know how to do my routing to accomplish such task. Thank you very much.
<-- This is a sample of how I do my routing in myApp (for only one view - "/view1") -->
Sample of app.js:
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'ngResource',
'ui.bootstrap',
'ngCookies',
'myApp.view1',
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
For each view there is a .js file associated where I defined its routing and controllers. For instance, for view "/view1" - view1.js:
'use strict';
angular.module('myApp.view1', ['ngRoute', 'ngResource'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', function($scope) {
// something
}]);
And a sample of my index.html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<script src="view1.js"></script>
<-- MORE SCRIPTS ARE LOADED -->
</head>
<body class="hamburg" ng-controller="MasterCtrl">
<-- SIDEBARS ARE DEFINED -->
<div id="content-wrapper">
<div class="page-content">
<!-- Main Content -->
<div class="row">
<div class="col-xs-12">
<div class="widget">
<div class="widget-body">
<div ng-view></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
Given the situation above looks like you want two page layout (page design or page template), the first one is now used in index.html, and the second one you want to use in login.html which just has two fields to fill out. So angular-ui/ui-router (doc url: https://github.com/angular-ui/ui-router/wiki) could be the solution to this issue.
The idea behind that is ui-router has a very powerful tool named ui-view which you can see it as a layout or template. So when the path is on any page other than login page like /index or /home use one ui-view, and on /login page then use another different ui-view.
For a rough example:
index.html page:
<html>
<head></head>
<body>
<div ui-view="layout"></div>
</body>
</html>
I assume you will reuse the head part, so just wrap every thing from the body in the original index.html and put into the new index.html. Same to the login page login.html.
config file:
$stateProvider
.state('index', {
url: '/index',
views: {
layout: {
templateUrl: "/path/to/index.html"
}
},
controller: 'indexController'
}
.state('login', {
url: '/login',
views: {
layout: {
templateUrl: "/path/to/login.html"
}
},
controller: 'loginController'
})
So what does the code above do is very similar to what you did with $routeProvider, it defines on which url use which controller and to load which view.
Hope this can help you, if any question let me know please.
You need to create your login page as a diferente ngApp, store your sesion on the localSotarge in case of a successfull login and then redirect to you main ngApp.
In your main ngApp, validate if a session exists in the localStorage and redirecto to the loginApp if it dont.
I know it sounds a bit like overdoing stuff, but I have not found any other solution in my 3 years working with AngularJS. Now, keep in mind that this is necesary because you need to NOT TO APPLY your index.html, and the only way to do that is using another ngApp.
Routing is used for injecting views in angular SPA. What I get from from your question is you need a login dialog.
For that you may look ngDialog or uibDialog
In your case you need to load new layout. I understand, for login and for application there is mostly different layout. This operation is equal to redirecting page to new location. With new angular app and controllers for login. You can use:
$window.location.href="new/layout/template".
Read more # Angular Dev Docs.

Angular ngRoute can't load template: Error [$compile:tpload]

I tried some simple Angular Routing, but I cant specify what's the error. Chrome just tells me that Angular can't compile the Template.
In the following Link you can see my directory structure.
directory-structure
-- angular.js
var testApp = angular.module('testApp', ['ngRoute']);
testApp.config(function($routeProvider){
$routeProvider.when('/list', {
templateUrl: 'pages/list.html',
controller: 'mainController'
}).when('/insert', {
templateUrl: 'pages/new.html',
controller: 'newController'
});
});
testApp.controller('mainController', function($scope){
$scope.message = 'main';
});
testApp.controller('newController', function($scope){
$scope.message = 'new';
});
--index.html
<!DOCTYPE html>
<html lang="en" ng-app="testApp">
<head>
<meta charset="UTF-8">
<title>Barfly</title>
<script src="/angular/angular.min.js"></script>
<script src="/angular-route/angular-route.min.js"></script>
<script src="/js/angularApp.js"></script>
</head>
<body ng-controller="mainController">
list
new
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
This is my error,
Browser Error
Thank you in advance!
EDIT. Sorry, I didn't see your directory structure. Are you sure pages directory is accessible to the public? Should the pages directory be moved into public directory?
Old answer:
The error is saying the templateUrl /pages/list.html does not exists. You should either save a template file into /pages/list.html file or add an inline template in the html body like this:
<script type="text/ng-template" id="/pages/list.html">
my template here
</script>
I encountered a sort of similar problem: templateUrl files could be not loaded (all resources didn't). In my case it happened when app was loaded on a browser on a mobile device. It was caused by Content Security Policy restrictions (How does Content Security Policy work?)
I got the CSP to permit all resources except for the templates referenced by templateUrl.
I also tried loading the templates through the script directive (https://docs.angularjs.org/api/ng/directive/script), but to no avail.
Eventually I decided to embed the templates in the route itself, like this:
testApp.config(function($routeProvider){
$routeProvider.when('/list', {
template: '<li ng-repeat="etcetera"></li>',
controller: 'mainController'
});
});
<a data-target="#list">list</a>
<a data-target="#insert">new</a>

Angular controller doesn't load

I have a very simple Angular controller set up, but the code inside its constructor isn't running. Here are the relevant pieces:
conversationcontrollers.js:
var exampleApp = angular.module('exampleApp',[]);
console.log('file loaded');
exampleApp.controller('ConversationController', ['$scope',
function($scope) {
console.log('controller constructor loads');
}
]);
conversation.html:
...
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<script src='/static/js/conversationcontrollers.js'></script>
...
<div ng-controller="ConversationController">
</div>
...
The files both load correctly according to the browser. But the only results from the console are:
file loaded
Can anyone help?
You'll also need an ng-app. This tells angular which part of your page is the angular application.
<div ng-app="exampleApp" ng-controller="ConversationController">
</div>

Categories

Resources