ng-include after application load - javascript

I currently have a server using handlebars to create an initial HTML page. In this page, I wish to have a ng-include to update the page on the client.
However, whenever my application runs, it loads the page, so the data-ng-include="template.url" loads template.url as it normally would. Is there anyway for ng-include to load this data after my application loads?
Here is a plunker. Look at the code inside index.html!

you can use
ng-if directive
just check for it initial loading , it will make your life easy
<ANY ng-if="expression">
//your code goes here
</ANY>
such as
<ANY ng-if="false">
// code will not execute
</ANY>
i hope this will help you
on your code
<body>
<div data-ng-controller="ctrl">
<div data-ng-include="template.url" ng-if="false">
Here is some stuff that I wish to remain until I press the button below.
</div>
<button type="button" data-ng-click="second()">Press me!</button>
</div>
based on your answer you should use your condition at your .js file here is your modified code
angular.module('myApp', [])
.controller('ctrl', ['$scope', function ($scope) {
$scope.templates =
[ { name: 'first.html', url: 'first.html'},
{ name: 'second.html', url: 'second.html'} ];
if (false){
$scope.template = $scope.templates[0];
}
$scope.second = function () {
$scope.template = $scope.templates[1];
};
$scope.first = function () {
$scope.template = $scope.templates[0];
};
}]);

Alternatively, you can use $location for your case, but for no more edited for your code, i can provide this solution for you:
Remove your code inside index.html file, so your code become like this:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div data-ng-controller="ctrl">
<div data-ng-include="template.url"></div>
</div>
</body>
</html>
2.Replace your script.js become like this:
angular.module('myApp', [])
.controller('ctrl', ['$scope', function ($scope) {
$scope.templates =
[ { name: 'init.html', url: 'init.html'},
{ name: 'first.html', url: 'first.html'},
{ name: 'second.html', url: 'second.html'} ];
$scope.template = $scope.templates[0];
$scope.second = function () {
$scope.template = $scope.templates[2];
};
$scope.first = function () {
$scope.template = $scope.templates[1];
};
}]);
3.Create file init.html with code inside:
Here is some stuff that I wish to remain until I press the button below.
<button type="button" data-ng-click="second()">Press me!</button>
Run it.

Related

How to use Angular with Require in javascript classes

I have been playing around with angular and would like to add it to application using require. I have a class called Test that is wrapped around a require for Angular. The problem is that if I do not initialize the angular.module directly under the require statement for angular, I get an error saying Uncaught Error: [$injector:modulerr]
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.3/require.min.js"></script>
<script>
require.config({
paths: {
"angular": "https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min"
}
});
</script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="name">
<h1>You entered: {{name}}</h1>
</div>
<script>
require(['angular'], function () {
var Test = class Test {
constructor() {
this.setAngular();
};
setAngular() {
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "John Doe";
});
}
}
});
var test = new Test();
</script>
</body>
</html>
However, if I move the require statement down to inside the setAngular function like so:
setAngular() {
require(['angular'], function () {
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "John Doe";
});
});
}
Then everything works fine. Am I missing something here?

Angular Js http GET response is displaying in console log but I am not able to display ng-view

AngularJS HTTP GET response is displaying in console log but I'm not able to display it inside div. Here is my code I'm beginner I don't figure out why it is not working so I'm asking here.
<!DOCTYPE html>
<html lang="en">
<base href="/">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-sanitize.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
</head>
<body>
testing
<div ng-app="myApp" ng-controller="newcontroller">
<div ng-bind-html="resultdata"></div>
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute","ngSanitize"]);
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when("/:id-wallpaper",{
templateUrl: "/new",
controller : "newcontroller"
});
$locationProvider.html5Mode(true);
});
app.controller("newcontroller", function ($scope, $http, $routeParams) {
$http({
url: "new",
method: "get",
params: { id: $routeParams.id }
}).then(function (response) {
console.log(response.data);
$scope.resultdata = response.data;
})
});
</script>
</div>
</body>
</html>
Please remove <div ng-bind-html="resultdata"></div> from your DOM and try to create a $route template. You will also be able create an additional file for your template by using templateUrl: 'nameOfTemplate.html' instead of binding it as an HTML-String by using template param. Please refer AngularJS routeProvider configuration.
$route configuration
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when("/:id-wallpaper",{
template: '<div>{{ resultdata }}</div>',
controller : "newcontroller"
});
$locationProvider.html5Mode(true);
});
With an template file it would look like this:
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when("/:id-wallpaper",{
templateUrl: 'myFile.html',
controller : "newcontroller"
});
$locationProvider.html5Mode(true);
});
Content of myFile.html (View)
<div>{{ resultdata }}</div>

cannot pass parameters via angular service between 2 html file

I have 2 html file and I want to pass parameters via angular service between them.
these are the files I have:
index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl2">
</div>
enter here
<script>
var app=angular.module("myApp");
app.controller("myCtrl2", ['$scope','$location', 'myService',
function($scope, $location, myService) {
myService.set("world");
}]);
</script>
</body>
</html>
enter2.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl3">
hello {{x}}
</div><script type="text/javascript">
var app=angular.module("myApp");
app.controller("myCtrl3", ['$scope','$location', 'myService',
function($scope, $location, myService) {
$scope.x=myService.get();
}]);
</script>
</body>
</html>
services.js
var app=angular.module("myApp", []);
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
});
why can't I get "hello world" in enter2.html, but instead get "hello" (x is not found by service)...?
When you go from index.html to enter2.html the whole page loads from scratch. For the data that you are expecting to stay in the browser, you might need to use advanced angular concepts such as loading just a part of the page using ng-view.
If that's something you have already overruled, saving the data in the service somewhere (may be the browser session) before unloading (window.onunload event) the page and then loading it back from there when the service loads (window.onload event) could also work.
Here is a working example based on your code.
I kept your index.html and added ui-view to have a single page application. The app uses 'ui.router'.
In the myCtrl2 I saved the data in the service, and call it back from myCtrl3:
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
To keep things simple, I have one Javascript file:
angular.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'myCtrl2',
controllerAs: 'vm'
})
.state('enter2', {
url: '/enter2',
templateUrl: 'enter2.html',
controller: 'myCtrl3',
controllerAs: 'vm'
});
})
.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
I also uses the var vm=this and ControllerAs as often recommended to avoid $scope issues.
index.html looks like below... pleaes note the ui-sref instead of href:
<div ui-view="">
<a ui-sref="enter2">Enter here</a>
</div>
enter2.html is now just the div part and your content:
<div>
Hello {{ vm.x }}
</div>
Let us know if that helps.
Additional info:
AngularJS Routing Using UI-Router
AngularJS's Controller As and the vm Variable
Sounds like you need to use a controller for your view page
https://docs.angularjs.org/guide/controller

Normalising controller in AngularJS

Am pretty new to AngularJS.
I have written a code and its working fine.
Would like to know, is there a way to further shrink the controller.
My index.html file is
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<input type="text" ng-model="sea" ng-change="newSearch()"/>
<ul>
<li ng-repeat="x in myData">
{{ x.name + ', ' + x.emailid}}
</li>
</ul>
</div>
<script src="js/app.js"></script>
<script src="js/controllers/maincontroller.js"></script>
</body>
</html>
And maincontroller.js is
app.controller('customersCtrl', function($scope, $http) {
$http(
{
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name':'powercom'}
})
.then(function(response) {
$scope.myData = response.data.records;
});
$scope.newSearch = function() {
$scope.newSea = $scope.sea;
$http(
{
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name':$scope.newSea}
})
.then(function(response) {
$scope.myData = response.data.records;
});
};
});
If you notice I have used the same $http function twice with a difference of param.
Thank you.
As #maurycy noted in his comment, the way to keep the size of your controllers small is to keep commonly used functionality inside of a service. Consider this service:
app.service('Customers',
[ '$http',
function($http) {
return {
byName: byName
};
function byName(name) {
return $http({
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name': name}
});
}
}
]
);
You can then use this service in a controller like this:
app.controller('customersCtrl', [
'$scope', 'Customers',
function($scope, Customers) {
$scope.myData = null;
Customers.byName('powercom')
.then(function(response) {
$scope.myData = response;
});
}
]);
Which is quite a bit shorter than what you have now, plus it is separated making it able to be used in any other part of your application (as well as much easier to test). If the endpoint changes, you have only a single spot to change and, since it's used everywhere else already, you're done.
Update
To bind on an ng-click, I'll assume you have an input bound to a local model, as well as a button for which to act as the click target, something like this:
<input type="text" data-ng-model="customerName" />
<button data-ng-click="lookupCustomer()">
Lookup Customer
</button>
Then in your controller, you can define the lookupCustomer function this way:
app.controller('customersCtrl', [
'$scope', 'Customers',
function($scope, Customers) {
$scope.customerName = 'powercom';
$scope.lookupCustomer = lookupCustomer;
$scope.myData = null;
lookupCustomer();
function lookupCustomer() {
Customers.byName($scope.customerName)
.then(function(data) {
// Do something with data
});
}
}
]);
You can add checks inside of lookupCustomer to guard against edge cases (no need to lookup an empty customer name), but this should work for you.
It'll be better if you'll create the service for getting your data.
app.service('dataService', function($http) {
this.get = function get(param) {
return $http({
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name': param}
});
}
});
app.controller('customersCtrl', function($scope, dataService) {
dataService.get('powercom').then(function(response) {
$scope.myData = response.data.records
});
$scope.newSearch = function() {
$scope.newSea = $scope.sea;
dataService.get($scope.newSea).then(function(response) {
$scope.myData = response.data.records
});
};
});
And also is not necessary to create a functions in your $scope. You can use "this" and get access for your data in controller by controller name or alias like this:
<div ng-controller="customersController as ctrl"><p ng-click="ctrl.newSearch">Hello</p></div>

Angular translate not working between 2 controllers

I would like to use i18n and i10n in my Angular app.
I read that Angular-translate can help with this, however, it doesn't work for me.
In my index.html:
<!DOCTYPE html>
<html ng-app="eApp">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="../common/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="../common/css/style.css" />
<title></title>
</head>
<body ng-controller="AppCtrl">
<div id="container" ng-view></div>
<!--- Libs Js files --->
<script type="text/javascript" src="../vendor/angularjs/angular.min.js"></script>
<script type="text/javascript" src="../vendor/angularjs/angular-route.min.js"></script>
<script type="text/javascript" src="../vendor/angularjs/angular-translate.min.js"></script>
</body>
</html>
In my eApp.js:
var eApp = angular.module('elbitApp', ['ngRoute', 'ui.bootstrap', 'config', 'pascalprecht.translate']);
// configure our routes
eApp.config(["$routeProvider",
function ($routeProvider) {
$routeProvider
// route for the home page
.when('/c', {
templateUrl: 'c/partials/c.html',
controller: 'CController'
})
// route for the about page
.when('/de', {
templateUrl: 'd/partials/dE.html',
controller: 'DEController',
resolve: {
data: function (DDataService) {
return DDataService.loadData().then(function (response) {
return response.data;
});
}
}
})
// route for the contact page
.when('/di', {
templateUrl: 'd/partials/di.html',
controller: 'DIController',
resolve: {
data: function (DDataService) {
return DDataService.loadData().then(function (response) {
return response.data;
});
}
}
}).otherwise({
redirectTo: '/di'
});
}]).config(["$httpProvider",
function ($httpProvider) {
// Configure the $httpProvider to parse date with date transformer
$httpProvider.defaults.transformResponse.push(function (responseData) {
convertDateStringsToDates(responseData);
return responseData;
});
}]).config(["$translateProvider",
function ($translateProvider) {
$translateProvider.translations('en', {
"TITLE": 'Hello',
"FOO": 'This is a paragraph.',
"BUTTON_LANG_EN": 'english',
"BUTTON_LANG_DE": 'german'
});
$translateProvider.translations('de', {
"TITLE": 'Hallo',
"FOO": 'Dies ist ein Paragraph.',
"BUTTON_LANG_EN": 'englisch',
"BUTTON_LANG_DE": 'deutsch'
});
$translateProvider.preferredLanguage('en');
}]);
// main controller that catches resolving issues of the other controllers
eApp.controller('AppCtrl', function ($rootScope) {
$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
alert("Cant resolve the request of the controller "); //TODO: add URL + additional data.
})
});
In this file I defined my app and added the $translateProvider and two dictionaries.
Afterwards I got to my deController.js:
eApp.controller('DispatcherEventsController', ['$scope', '$route', '$translate',
function($scope, $route, $translate){
var data = $route.current.locals.data;
$scope.title = $translate.instant("FOO");
$scope.switchLanguage = function(languageKey){
$translate.use(languageKey);
};
}]);
In de.html I added a h1 tag with FOO and in a click I would like to change to German:
<h1>{{title |translate}}</h1>
<h1 translate="{{title}}"></h1>
<button type="button" id="searchButton" class="btn btn-default" ng-click="switchLanguage('de')">German</button>
I don't get any problem, but nothing happens. I expected that the English title will be converted to German title.
What can I do to make this work?
It works well for me. Here is a jsFiddle DEMO.
In this case, you want to bind $scope.title with translation key "FOO".
You should change the value of $scope.title dynamically in the switchLanguage function. Then view will be updated accordingly.
//default value
$scope.title = $translate.instant("HEADLINE");
$scope.switchLanguage = function(key){
$translate.use(key);
$scope.title = $translate.instant("HEADLINE");
}
In my opinion, maybe use translation key is a better way than scope data binding. You don't have to maitain the value of key manually.
<h1>{{'FOO' | translate}}</h1>
According to the error msg you provided, maybe you could check if there is any typo syntax in your controller.
Should be
$translate.use(languageKey)
Not
$translate.uses(languageKey)
Though not directly related to your question - you must remember to set the preferred language in the translations.js file, or whatever its name is that you define your key-value translations. Otherwise it will just default to whatever the key is.
...
GREETING: 'Hello World!',
...
$translateProvider.preferredLanguage('en');
Without this line, when doing this:
<h2>{{'GREETING'|translate}}</h2>
Would appear as just GREETING instead of the 'Hello World.'

Categories