AngularJS : accessing global variable within html template - javascript

I am writing an angularJs app:
html :
<div ng-controller=NavCtrl>
<h1 ng-bind-html="currentTitle"></h1>
</div>
I am searching for a way to update the currentTitle variable in my html which is in global scope.
.service('WorkService', [function(){
return {
currentTitle : 'dada'
};
}])
.controller('NavCtrl', function($scope, $location, $http, WorkService) {
$scope.works = [];
$http({method: 'GET', url: '/api/v1/work'}). //collects all works
success(function(data, status, headers, config) {
$scope.currentTitle = WorkService.currentTitle;
})
})
.controller('DetailCtrl', function($scope, $routeParams, $http, WorkService) {
$http({method: 'GET', url: '/api/v1/work/' + $routeParams.workId + '/'}).
success(function(data, status, headers, config) {
$scope.activateButton($routeParams.workId);
WorkService.currentTitle = data.title;
})
})
But currentTitle variable is not updated in the template. What am i doing wrong?

When you do WorkService.currentTitle = data.title current scope is unaware of this change. That is why you wont see the change in the template.
It is not ideal but for this requirement you may keep the currentTitle in $rootScope and keep update $scope.currentTitle in each controllers and that will do.
.run(function($rootScope){
$rootScope.globalData = {currentTitle : 'dada'}
})
.controller('NavCtrl', function($scope, $location, $http, WorkService) {
$scope.works = [];
$http({method: 'GET', url: '/api/v1/work'}). //collects all works
success(function(data, status, headers, config) {
$scope.globalData.currentTitle = 'New title';
})
})
.controller('DetailCtrl', function($scope, $routeParams, $http, WorkService) {
$http({method: 'GET', url: '/api/v1/work/' + $routeParams.workId + '/'}).
success(function(data, status, headers, config) {
$scope.activateButton($routeParams.workId);
$scope.globalData.currentTitle = data.title;
})
})
And in html
<h1 ng-bind-html="globalData.currentTitle"></h1>

You can't two-way bind to a variable in a service, but you can bind to an accessor function. Change your service to return getter and setter functions:
.service('WorkService', ['$sce', function($sce){
var currentTitle= $sce.trustAsHtml('dada');
return {
getCurrentTitle: function(){ return currentTitle; },
setCurrentTitle: function(value){ currentTitle = $sce.trustAsHtml(value);}
};
Then in your controller you can get the currentTitle like this:
$scope.currentTitle = WorkService.getCurrentTitle;
Note that you are setting it equal to the getCurrentTitle function itself (not the result of the function).
Now your html looks like this:
<h1 ng-bind-html="currentTitle()"></h1>
No need to set up $watches or hang stuff of $rootScope. See Demo here.

Related

How can I gain access to a Javascript variable from within a return function?

function storyData($http, $q) {
var URL = 'stories.json';
var storyCache = [];
this.getStories = function() {
var deferred = $q.defer();
alert(URL);
$http({method: 'GET', url: URL})
.success(function (data, status, headers, config) {
storyCache = data;
alert(storyCache); //correct data appears in the alert window, but this doesn't set the instance storyCache variable for some reason
deferred.resolve(data);
})
.error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
};
this.stories = function() {
return storyCache;
}
}
My app -
'use strict';
var angularApp = angular.module('ccsApp', ['ngRoute', 'ngAnimate', 'ui.bootstrap']);
angularApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'stories.html',
controller: 'StoryController as StoryCtrl',
resolve: {
stories: function(storyData) {
return storyData.getStories();
}
}
})
.otherwise({
redirectTo: '/'
});
}
]);
Within my controller, I'm not injecting the "stories" value from the routeProvider so that I can use my service.
Why am I unable to change storyCache from within my $http method? I'm confident this is something terribly simple, but my research hasn't led me to an answer. Thank you in advance for your help.
The async. aspect of this works fine and is not the problem. I'm ensuring that I have the data by using the resolve object on my routeProvider. Also, I'm ensuring that I have the data before the deferred.resolve(data) method executes by issuing an alert on it. I don't have the solution, but an error in my use of async. is not the solution either.

Angular - Break line text

I can't save break line text into my database, how to solve this issue?
My save data suppose to be like this
I want to ask something.
Can I?
Not like this
I want to ask something. Can I?
html
<textarea name="" cols="" rows="" class="form-control" ng-model="rule.message" required></textarea>
<button type="submit" class="btn btn-default" ng-click="create()">Save</button>
js
myControllers.controller('MemberRuleCreateCtrl', ['$scope', '$location',
'$http',
function($scope, $location, $http) {
$scope.rule = {};
$scope.create = function() {
$http({
method: 'GET',
url: 'http://xxxxx.my/api/create_rule.php?&message=' + $scope.rule.message
}).
success(function(data, status, headers, config) {
alert("Rule successful created");
$location.path('/member/rule');
}).
error(function(data, status, headers, config) {
alert("No internet connection.");
});
}
}
]);
Just use the encodeURIComponent() function to encode the newlines correctly into the URL so it will be seen by the server correctly when you submit the GET request.
So your JS becomes:
myControllers.controller('MemberRuleCreateCtrl', ['$scope', '$location',
'$http',
function($scope, $location, $http) {
$scope.rule = {};
$scope.create = function() {
$http({
method: 'GET',
url: 'http://xxxxx.my/api/create_rule.php?&message=' + encodeURIComponent($scope.rule.message)
}).
success(function(data, status, headers, config) {
alert("Rule successful created");
$location.path('/member/rule');
}).
error(function(data, status, headers, config) {
alert("No internet connection.");
});
}
}
]);

Having trouble getting a factory to be recognized in angular controller

I'm trying to pass data from one controller to another using a factory and for some reason my factory isn't getting recognized in angular seed. Here is my app.js file which I'm declaring my factory
var myApp = angular.module('myApp', ['myApp.controllers','angularFileUpload', 'ngRoute']);
//
//
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/' ,{templateUrl:"/syncproto/partials/videoSlides.html"}, "sync").
when('/scenarios', {templateUrl:"/syncproto/partials/scenarios.html"}, "scenariosCtrl").
when('/scenarios/:id', {templateUrl:"/syncproto/partials/scenarios.html"}, "scenariosCtrl")
}]);
myApp.factory('Data', function() {
var Data;
return {
getData: function () {
return Data;
},
setData: function(value) {
Data = value;
}
};
});
Here is the controller which I'm using the factory Data
.controller('scenariosCtrl', ['$scope', '$http', '$location', 'Data', function($scope, $http, Data) {
$scope.scenarios = [];
$scope.thumbnails = [];
$scope.init = function(){
console.log('init hit');
$http({ method: 'GET', url: 'http://localhost:3000/scenarios' }).
success(function (data, status, headers, config) {
angular.forEach(data, function(scenario) {
if (scenario.video.length != 0 && scenario.video[0].thumbnailLocation != undefined){
$scope.thumbnails.push(scenario.video[0].thumbnailLocation);
//console.log('thumbnail is' + scenario.video.thumbnailLocation);
$scope.scenarios.push(scenario);
console.log(scenario.video[0].thumbnailLocation);
}
});
//console.log($scope.scenarios);
console.log('success');
}).
error(function (data, status, headers, config) {
console.log('error');
});
console.log($scope.thumbnails);
}
$scope.showVideo = function(scenario){
Data.setData(scenario);
$location.path('/');
//Data.setData($scope.scenarios[$scope.thumbnail.indexOf(thumbnail)]);
}
}])
The problem is that in $scope.showVideo = function(scenario) when i call Data.setData(scenario); I get the error TypeError: Object #<Object> has no method 'setData'
.controller('scenariosCtrl', ['$scope', '$http', '$location', 'Data', function($scope, $http, Data)
You're missing one argument for the $location service here. It should be
.controller('scenariosCtrl', ['$scope', '$http', '$location', 'Data', function($scope, $http, $location, Data)

Can I change which JSON file is loaded by sending a variable to AngularJS?

I would like to load the content of one of two JSON files, food1.json or food2.json. I am trying to do this from the html template:
<body ng-controller="MainCtrl" ng-init="init('food1')">
And then in the JS:
$scope.init = function (name) {
$scope.name = name;
$scope.category = name + ".json";
$scope.foodlist = {};
$http({
method: 'GET',
url: $scope.category,
}).success(function (data, status, headers, config) {
{
$scope.foodlist = data;
}
}).error(function (data, status, headers, config) {
// something went wrong :(
});
};
});
The category name is properly assembled: I get "I am food1" if I print I am {{ category }}. But no food items are printed. I think I am doing the JSON call wrong.
Here's my Plunkr
You have not injected $http in the controller. Change you code as
app.controller('MainCtrl', function($scope, $http) {
instead of
app.controller('MainCtrl', function($scope) {
DEMO

How do I access a url parameter inside a controller?

I have a controller that needs to access a url parameter. However, I can't figure out how to access the parameter. Here is what I have so far:
Controller:
function CustomerCtrl($scope, $http, $routeParams, $route) {
// var customer_id = $routeParams.id; // this doesn't work
// var customer_id = $route.current.params.id; // this doesn't work
var customer_id = '58'; // this clearly works
$http({
url: 'customers/'+customer_id+'/info',
method: "POST"
})
.success(function (data, status, headers, config) { $scope.name = data; })
.error(function (data, status, headers, config) { $scope.status = status; });
}
App:
var customer = {
name: 'customer',
url: '/customer',
abstract: true,
templateUrl: 'views/customer/customer.html',
controller: 'CustomerCtrl'
};
var customer_info = {
name: 'customer.info',
parent: customer,
url: '/:id/info'
views: {
view1: { templateUrl: "views/customer/view1.html" },
view2: { templateUrl: "views/customer/view2.html" }
}
};
$stateProvider
.state(customer)
.state(customer_info);
What am I missing?
It's actually even easier than you thought. You're using the ui-router (https://github.com/angular-ui/ui-router) which uses states instead of the default router.
function CustomerCtrl($scope, $http, $routeParams, $route) {
should be:
function CustomerCtrl($scope, $http, $stateParams, $state) {
then:
var customer_id = $stateParams.id;
I spent all day confusing myself by trying to find an angular solution to this seemingly simple, common problem. Most of you probably already figured this out, but the solution is to just use plain old javascript:
var pathArray = window.location.pathname.split( '/' );
var customer_id = pathArray[3];
$scope.customer_id = customer_id
So simple, yet I feel like an idiot for not thinking about this from the beginning.

Categories

Resources