AngularJS JSFiddle and http service - angularjs

I'm working on an angularJS app and I can't seem to retrieve my JSON object from the url. Not sure what I'm doing wrong...
var app = angular.module("app", []);
app.controller("mainCtrl", function($scope, $http) {
var url = "https://jsfiddle.net/Afroza/j35e8v8h/r";
$http.get(url).then( funtion(response) {
$scope.info = response.data;
})
});
Here's my html:
<div ng-app="app" ng-controller="mainCtrl">
<div>
<h1>Hello World</h1>
<p>Data: {{info}}</p>
</div>
</div>
Also, I'm using JSFiddle so all the html tags and angularjs scripts are included.

You spelling of function is wrong. Its funtion in your code.
$http.get(url).then( function(response) {
$scope.info = response.data;
})
You can always check console ctrl+shift+j in chrome to check syntax and other js related errors.
Working fiddle : https://jsfiddle.net/j35e8v8h/18/

Related

Async variable stored in $rootScope not available in other controllers

I am using Angular 1.x for my stack and when I make an API call and store the response in the $rootScope, it is not accessible in other controllers' view.
My controller:
angularApp.controller('mainController', ['$scope', '$rootScope', '$http', function($scope, $rootScope, $http){
var checkIfAuthenticated = function(){
return $http.get('/api/isAuthenticated');
};
checkIfAuthenticated()
.then(function(res) {
if(res.status===200){
console.log("Success");
$rootScope.userLoggedIn = true;
}
})
}]);
Now, in another controller's view I use it like this:
<div ng-if="userLoggedIn" class="py-1 pl-1 pr-1">
<span><b>Message Board</b></span>
<div class="form-control" readonly id="lockTextbox">Show something</div>
</div>
The problem is, the API call /api/isAuthenticated does provide the right response (status 200) but the ng-view gets it wrong.
I am sure this is to do with $rootScope.userLoggedIn being a response from an async call (as I get Success in my console) but how do I solve it?
Thanks in advance!
EDIT
After I posted the question, I noticed that in the mainController's view, the ng-if logic doesn't work either. What is very strange is that when I open up the browser's debug console, it starts working! I think this is just an async issue but I don't know how to solve it. How do I tell the view that the variable is on it's way?
OK, to solve the timing issue, I'll rework the answer completely. This should be a - quick and dirty but - working example:
index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="plunker" ng-cloak>
<div ng-controller="MainCtrl as $ctrl">
<h1>Hello {{$ctrl.name}}</h1>
<p>Start editing and see your changes reflected here!</p>
<div ng-if="$ctrl.name === 'Angular.js'"><b>Message Board</b</div>
</div>
</body>
</html>
script.js
import angular from 'angular';
angular.module('plunker', []).controller('MainCtrl', function($scope, $http) {
const self = this;
self.name = 'Plunker';
console.log('hello');
function checkIfAuthenticated(){
console.log('get');
return $http.get('https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js');
};
checkIfAuthenticated().then(function(res) {
if(res.status===200){
console.log('Success');
self.name = 'Angular.js'; // insert any logic here
} else {
console.log('Failed');
}
})
});
Console
hello
get
Success
Does it work for you?
Working Example
The below demo shows the $rootScope variable available in both controllers after being set from a promise delayed by two seconds.
angular.module("app",[])
.controller('mainController', function($scope, $rootScope, $timeout) {
var checkIfAuthenticated = function(){
return $timeout(function() {
return { status: 200 };
}, 2000);
};
checkIfAuthenticated()
.then(function(res) {
if(res.status===200){
console.log("Success");
$rootScope.userLoggedIn = true;
}
})
})
.controller('otherController', function($scope) {
console.log("other controller");
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<fieldset ng-controller="mainController">
MAIN Controller userLoggedIn={{userLoggedIn}}<br>
<div ng-if="userLoggedIn">
Message Board - Show something
</div>
</fieldset>
<fieldset ng-controller="otherController">
OTHER Controller userLoggedIn={{userLoggedIn}}
<div ng-if="userLoggedIn">
Message Board - Show something
</div>
</fieldset>
</body>
I found the problem. I updated my Angular from 1.6.4 to 1.7.9 (and all modules like angular-sanitize etc) and that did the trick. Should have been the first thing I did but I missed it entirely

Play Framework + Angular Issue with JSON render on Page

I have simple Scala Play Framework and Angular application. I tried to render JSON data on play's "xxx.scala.html" template but don't know what is the problem it is not rendering as expeted.
#main("Welcome to Play") {
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"> </script>
<script>
app.controller('NamesCtrl', function($scope) {
// get names using AngularJS AJAX API
$http.get('/getNames').success(function(data){
$scope.names = data;
});
});
</script>
<div ng-app="app" ng-contoller="NamesCtrl">
<ul>
<li ng-repeat=" name in names">{{name}}</li>
</ul>
</div>
}
My route entry
GET /getNames controllers.HomeController.getNames
Scala Controller:
def getNames = Action {
val names = List("Bob","Mike","John")
Ok(Json.toJson(names)).as(JSON)
}
When I am calling my page using url
http://localhost:9000/getNames
I was getting response on page as below,
["Bob","Mike","John"]
Please can you explain what am I doing wrong here?
Thanks !!
There are some problems in the code. The correct one is this:
#main("Welcome to Play") {
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.19/angular.min.js"></script>
<div ng-app="myApp" ng-controller="NamesCtrl">
<ul>
<li ng-repeat="name in names">{{name}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('NamesCtrl', function($scope, $http) {
$http.get('/getNames').success(function(data){
console.log(data);
$scope.names = data;
});
});
</script>
}
What has changed:
AngularJS 1.3.19 instead of 1.2.10
AngularJS module - which is referenced in the div
injected the $http service in the controller
your ng was wrong - it should be ng-controller instead of ng-contoller (a typo I guess)
The result is what you would expect:

angular ng-repeat and array from js

I'm tring to repeat an array in the html
html:
<div class="personWrapper" ng-repeat="message in messages">
<p>{{message}}</p>
</div>
js:
var app = angular.module('matcherApp', [ "ngRoute", "ngStorage" ]);
app.config(function($routeProvider) {
$routeProvider.when('/Messages', {
templateUrl : 'menu/messages.php',
controller : 'messagesController'
})
});
app.controller('messagesController', function($scope, $localStorage) {
console.log("im in messages page!!!");
var messagesUsers = [];
$.post("db.php", {
'messagesWindow' : "messagesWindow",
'myProfileId' : JSON.parse(localStorage.getItem("myProfileDetails")).id
}, function(data) {
data = $.parseJSON(data);
angular.forEach(data, function(key, value) {
angular.forEach(key, function(key2, value2) {
messagesUsers.push(key2.Name);
});
});
console.log(messagesUsers);
$scope.messages = messagesUsers;
}).fail(function() {
alert("error bringing messages data");
});
});
the console.log show me:
im in messages page!!!
["a","b"]
that works with all different controllers in the same app.
its not showing me on the dom any loop.
what am i doing wrong? thanks.
Works for me! Look
var app = angular.module('MessagesApp', []);
app.controller('MessagesController', function($scope) {
$scope.messages = ["a", "b"];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MessagesApp" ng-controller="MessagesController">
<div class="personWrapper" ng-repeat="message in messages">
<p>{{message}}</p>
</div>
</div>
JS Code looks like below:
var app = angular.module('modelapp', []);
app.controller('ctrl', function($scope) {
$scope.emplist = ["john", "marry", "jaison"];
});
HTML Code:
<div ng-app="modelapp" ng-controller="ctrl">
<div ng-repeat="data in emplist">
<p>{{data}}</p>
</div>
</div>
It will load entire list, You can add class for div as per design, Even you can track index number also by using $index directive.

Controller triggered via factory

I am still a novice with angular. I have asked a question similar to this before, but it seems to be a different issue at work here.
I have two controllers and a factory sharing information between them. I have two separate divs using two different controllers to show / hide using ng=show;
HTML
<div id=main>
<div ng-controller="Ctrl1">
<div ng-show="var1">Hidden Stuff</div>
</div>
<div ng-controller="Ctrl2">
<div ng-show="var1">More Hidden Stuff</div>
</div>
</div>
Both use the same var for ng-show, shared by a factory
JS Factory
app.factory('Srvc', function($rootScope) {
var Srvc = {};
Srvc.var1;
return Srvc;
});
JS Controllers
app.controller('Ctrl1', function($scope, Srvc) {
$scope.var1 = false;
if (user interacts with html in div with ng-controller="Ctrl1") {
$scope.var1 = true;
Srve.var1 = $scope.var1;
}
});
app.controller('Ctrl2', function($scope, Srvc) {
$scope.var1 = Srvc.var1;
if ($scope.var1 === true) {
update HTML in div with ng-controller="Ctrl2"
although I shouldn't need to do this really should I?
}
});
So from what I can tell the factory works ok, the data is saved in the factory Srvc.var1. However when I pass the data true to Srvc.var1 I cannot seem to get Ctrl2 to 'trigger' and update its html with ng-show=true
One way to solve this problem without explicitly creating a watcher, is to wrap var1 in an object inside the service and then pass this object as a $scope variable for both Ctrl1 and Ctrl2 controllers.
DEMO
Javascript
.factory('Svc', function() {
var service = {
data: {}
};
// If you perform http requests or async procedures then set data.var1 here
service.data.var1 = true;
return service;
})
.controller('Ctrl1', function($scope, Svc) {
$scope.data = Svc.data;
})
.controller('Ctrl2', function($scope, Svc) {
$scope.data = Svc.data;
});
HTML
<div id="main">
<div ng-controller="Ctrl1">
<div ng-show="data.var1">Hidden Stuff</div>
<button type="button" ng-click="data.var1 = true">Set data.var1 to true</button>
<button type="button" ng-click="data.var1 = false">Set data.var1 to false</button>
</div>
<hr>
<div ng-controller="Ctrl2">
<div ng-show="data.var1">More Hidden Stuff</div>
<button type="button" ng-click="data.var1 = true">Set data.var1 to true</button>
<button type="button" ng-click="data.var1 = false">Set data.var1 to false</button>
</div>
</div>
So it seems I need to $watch the service for a change within the controller.
Original answer is here.
app.controller('Ctrl2', function($scope, Srvc) {
$scope.$watch(function () {
return Srvc.var1;
},
function(newVal, oldVal) {
$scope.var1 = newVal;
}, true);
});
I think setting Var1 to $rootScope instead of Srvc should work, just call $scope.$root.$digest() after updating var1.
and use ng-show=$root.Var1 in view.

Very simple ng-model watch not working

Here is the jsfiddle.
http://jsfiddle.net/CLcfC/
code
var app = angular.module('app',['']);
app.controller('TestCtrl',function($scope){
$scope.text = 'Change Me';
$scope.$watch('text',function(){
alert('Changed !');
});
})
HTML
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="TestCtrl">
<input type="text" ng-model='text'/>
<span>{{text}}</span>
</div>
</div>
I am not able to see the change in $scope.text. Please help.
This is so easy but what am I missing?
Change the module creation to this, make sure you don't put a empty string in the []. (Obvious the empty string is not a module that can be injected.)
var app = angular.module('app', []);
Demo: http://jsfiddle.net/MWa66/
Your JavaScript file loads after the AngularJS initialization and that's why it fails to find your module. In order to fix it change the initialization to a manual initialization.
First change your HTML and remove the ng-app directive:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div id="appRoot">
<div ng-controller="TestCtrl">
<input type="text" ng-model='text'/>
<span>{{text}}</span>
</div>
</div>
Then go to your JavaScript and use angular.bootstrap method to manually attach your module:
var app = angular.module('app',[]);
app.controller('TestCtrl',function($scope){
$scope.text = 'Change Me';
$scope.$watch('text',function(){
alert('Changed !');
});
});
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('appRoot'), ['app']);
});
You can find more help on manual AngularJS initialization here.
Thank you! I solved this annoying thing!
The solution that worked for me was that I use angular UI router and there I had used the following code
.state('app.monimes', {
url: "/monimes",
views: {
'menuContent' :{
templateUrl: "templates/monimes.html",
controller: 'sampleCtrl'
}
}
})
so then in the controller I had
/***
*
*Controller for tests..
*/
.controller('sampleCtrl',['$scope','sampleService', function($scope, $sampleService) {
$scope.username="em";
// Watch for changes on the username property.
// If there is a change, run the function
$scope.$watch('username', function(newUsername) {
// uses the $http service to call the GitHub API
// //log it
$scope.log(newUsername);
// and returns the resulting promise
$sampleService.events(newUsername)
.success(function(data, status, headers) {
// the success function wraps the response in data
// so we need to call data.data to fetch the raw data
$scope.events = data.data;
});
},true);
}
]);
and in the view I had
<div>
<label for="username">Type in a GitHub username</label>
<input type="text" ng-model="username" placeholder="Enter a GitHub username, like a user" />
<pre ng-show="username">{{ events }}</pre>
</div>
but that didn't work.
so I added ng-controller="sampleCtrl"
to the div and now it works :D
so that means that the view is loaded after the controller loads and the watcher doesn't get added to the watching variable.

Resources