Loading controller js files using require.js - angularjs

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.

Related

How to put controllers and factories in separate files

I have one module 'app' and I am trying to separate it's controllers and one factory into individual files. The app works when I chain all controllers in the main app.js file. It breaks instantly when I try to move them to new files.
I've tried everything to get my controllers/factories in a separate file but I constantly get this error:
[$controller:ctrlreg] The controller with the name 'AppCtrl' is not registered.
https://errors.angularjs.org/1.7.2/$controller/ctrlreg?p0=AppCtrl
I have declared the scripts in the main html file.. All of the js files are in the same directory. I am attempting to add the controller using angular.module('app) as the reference to the main module, but nothing works.
My directory structure:
|app
| app.js
| AppCtrl.js
|public
|index.html
app.js
angular.module('app', ['ngRoute']);
angular.module('app')
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
template: require('./home.html'),
controller: 'AppCtrl'
})
$locationProvider.hashPrefix('');
});
AppCtrl.js
angular.module('app')
.controller('AppCtrl', function ($scope, $route) {
//controller code
});
index.html
<!doctype html>
<html ng-app="app" lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="/img/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<script src="../app/app.js"></script>
<script src="../app/AppCtrl.js"></script>
<base href="/">
</head>
Am I missing a step on getting these separated out?

Unable to navigate to a VueJS webapp from AngularJS index.html

I was trying to merge AngularJS and VueJS projects together since we need to have a requirement of calling the flow designed in VueJS from inside an AngularJS app. For merging AngularJS and VueJS projects together, I included the dependencies in package.json file of Angular and Vue together and few other files too.
Now since both Vue and Angular have an index.html file created in the project root directory, I made the Angular one as my index.html file and renamed VueJS index file as index23.html. Then from the link from where I need to call VueJS flow, I provided the path in the router of AngularJS config file as shown:
'use strict';
app.config(function ($routeProvider) {
$routeProvider
.when("/errorinput", {
templateUrl: "src/index23.html"
});
});
app.controller('ErrorInputCtrl', ['$scope', '$http', function ($scope, $http) {
// Implement me!
}]);
But on doing so, my VueJS page doesn't comes up but rather it comes up in background I think as current page gets surrounded with a white background on clicking that link. I am really not sure if I need to code something inside the app.controller method of above file since this is a Vue component which I am talking about.
Is there any way we can make this work? Please let me know if I need to provide additional details. Contents of index.html file from where this call is made are below:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SEW Drive Status| </title>
<!-- Bootstrap -->
<link href="node_modules/gentelella/vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="node_modules/gentelella/vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<!-- Custom Theme Style -->
<link href="node_modules/gentelella/build/css/custom.min.css" rel="stylesheet">
<!-- Angular JS Material -->
<link href="node_modules/angular-material/angular-material.min.css" rel="stylesheet">
<!-- Angular JS Material -->
<!--link href="public/material.css" rel="stylesheet"-->
</head>
<script src="node_modules/angular/angular.min.js" ></script>
<script src="node_modules/angular-route/angular-route.min.js" ></script>
<script src="node_modules/angular-aria/angular-aria.min.js"></script>
<script src="node_modules/angular-material/angular-material.min.js"></script>
<script src="app/app.js" ></script>
<!-- custom control script section -->
<script src="app/components/assetlist.js" ></script>
<script src="app/components/errorinput.js" ></script>
<script src="bundle.js"></script>
<li><a><i class="fa fa-edit"></i>Administration<span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><i class="fa fa-database"></i>Manage Error Descriptions</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- /sidebar menu -->
This is the Angular page and link(Manage Error Descriptions) from where I need to call VueJS app:
White background issue:
errorinput.js file after adding the code:
'use strict';
app.config(function ($routeProvider) {
$routeProvider
.when("/errorinput", {
templateUrl: "views/errorinput.html"
});
});
app.controller('ErrorInputCtrl', ['$scope', '$http', function ($scope, $http) {
// Implement me!
<template>
<div class="container">
<div>
<transition name="fade">
<router-view></router-view>
</transition>
</div>
</div>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-active {
opacity: 0
}
</style>
<script>
export default{
}
</script>
}]);
Vue and Angular can co-exist on a page just fine.
Because you're using Angular to render Vue's HTML, you'll need to make sure your Vue initialization fires after the new HTML is rendered. You could accomplish this a couple of ways:
Paste your Vue script where it says // Implement me in your code above
Use a hook in your Angular router to load your Vue-specific .js file after the route has loaded
First option is probably more performant, while second option probably keeps your dev setup cleaner.

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.

Angular + Laravel + UI-Router Issue

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.

Using Zurb Foundation Interchange with AngularJS

I'm working on an AngularJS project that uses Zurb Foundation as its CSS framework. I'm trying to figure out how to using Foundation's data interchange within the context of an AngularJS view. Is this even possible, I can't seem to get it to work. This is what I currently have:
index.html
<!DOCTYPE html>
<html ng-app='app' xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="foundation/normalize.css" />
<link rel="stylesheet" href="foundation/foundation.min.css" />
<link rel="stylesheet" href="app.css" />
</head>
<body>
<div id="view" ng-view></div>
<script type="text/javascript" src="jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript" src="foundation/foundation.min.js"></script>
<script type="text/javascript" src="angularjs/1.2.7/angular.min.js"></script>
<script type="text/javascript" src="angularjs/1.2.7/angular-route.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
app.js
angular.module('app', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.otherwise({ templateUrl: '/views/interchange.html', controller: myCtrl });
})
.run(function ($rootScope, $location) {
$rootScope.$on('$viewContentLoaded', function () {
$(document).foundation();
});
})
;
function myCtrl() {
console.log('loading controller');
}
interchange.html
<article>
testing interchange
<div data-interchange="[phone.html, (small)], [portrait.html, (medium)], [landscape.html, (large)]"></div>
</article>
When I load my app, I can see 'testing interchange'. However, the content (phone.html, portrait.html, landscape.html) based on the size of the screen is not shown. Phone.html, Portrait.html, and landscape.html just have text inside DIV elements that say 'Phone', 'Portrait', and 'Landscape' effectively.
Is there a way to leverage Foundation's data interchange stuff inside of a AngularJS ng-view? If so, how? Thank you
The main point here is that the data-interchange feature of Zurb runs on DOMContentLoad event, and the load of AngularJS' views is async. So, the event already happened.
To get over this, you need to trigger the data-interchange manually using $(document).foundation('interchange', 'reflow'); or $(document).foundation('reflow'); to reflow all components.
To trigger this on the right place, you need to listen to a special event on AngularJS routing system called $routeChangeSuccess. Something like this:
module.run(function ($rootScope) {
$rootScope.$on('$routeChangeSuccess', function () {
$(document).foundation('reflow');
});
});
Hope this help you.

Resources