Play Framework + Angular Issue with JSON render on Page - angularjs

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:

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

Angular Json Http Get - Not load

This is a simple test to fetch json file from third party server, but no success. I did test with this json (https://jsonplaceholder.typicode.com/posts) and is working. Any body can help me? Thanks in advance.
var app = angular.module("viewJSON",[]);
app.controller("viewCtrl",function Hello($scope, $http) {
$http.get('http://media.astropublications.com.my/api/drebar_landing.json').
success(function(data) {
$scope.testJer = data;
$scope.keys = Object.keys($scope.testJer[0]);
});
});
section {height:180px;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<div ng-app="viewJSON" ng-controller="viewCtrl">
<div ng-repeat="item in testJer | filter:search">
<section class="col-md-3">
<h4>{{item.Title}}</h4>
<p>{{item.Description}}</p>
</section>
</div>
</div>
You need to access the ArticleObject array from the response ,
app.controller("viewCtrl", function Hello($scope, $http) {
$http.get('http://media.astropublications.com.my/api/drebar_landing.json').
success(function(data) {
$scope.testJer = data.ArticleObject;
});
});
PLUNKER DEMO

AngularJS JSFiddle and http service

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/

ng-repeat only showing 2 elements of array

The ng-repeat is only showing the first 2 elements of the array (there are 25). What is wrong?
I'm a newbie with Angular. I am lost with the cause of it, no errors in console. Any suggestions?
<div ng-app="myApp" id="posts" ng-controller="myCtrl as posts">
<li ng-repeat="post in posts" track by $index>
<p>{{posts.data.children[$index].data.ups}}</p>
<p>{{posts.data.children[$index].data.title}}</p>
</li>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
var vm = this;
vm.mydata = [];
$http.get("http:/www.reddit.com/.json")
.then(function(response) {
vm.mydata = response.data;
$scope.posts = vm.mydata;
//console.log(vm.mydata);
//console.table(vm.mydata);
}, function(response) {
$scope.posts = "Something went wrong";
});
});
</script>
Final code corrected. This is a very basic script to manage the extraction of posts in the Reddit's front page and displayed it in descending order by upvotes. Thank you all for your help! See code below:
<!DOCTYPE html>
<html>
<!-- _________________________________________________________-->
<!-- Framework: AngularJs -->
<!-- Author: Vanessa Torres -->
<!-- Date: March 30, 2016 -->
<!-- Description: Reddit's Front page posts extraction -->
<!-- _________________________________________________________-->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" id="posts" ng-controller="myCtrl as posts">
<li ng-repeat="post in posts.data.children | orderBy:'-data.ups'" track by $index>
<p>{{post.data.ups}}</p>
<p>{{post.data.title}}</p>
<p>{{post.data.url}}</p>
</li>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.posts = [];
$http.get("http:/www.reddit.com/.json")
.then(function(response) {
$scope.posts = response.data;
console.table(vm.mydata);
//
}, function(response) {
$scope.posts = "Something went wrong";
});
});
</script>
</body>
</html>
Because you are iterating over posts which have basically two properties only ups and title
Use:
<li ng-repeat="post in posts.data.children" track by $index>
<p>{{post.data.ups}}</p>
<p>{{post.title}}</p>
</li>
The HTML should be as given below:
<div ng-app="myApp" id="posts" ng-controller="myCtrl as posts">
<li ng-repeat="post in posts track by $index">
<p>{{post.data.children.data.ups}}</p>
<p>{{post.data.children.data.title}}</p>
</li>
</div>
This iterates inside the posts array and the value of each post keys (ups and title) is displayed. Please check the documentation for ng-repeat (https://docs.angularjs.org/api/ng/directive/ngRepeat) for the correct format of using track by $index.
As a basic coding standard, you need not use var vm = this; along with $scope. If you are using the vm variable, then inside routes (or inside directives), where you associate each route (or directive) with a controller, you can add an extra field controllerAs for aliasing the controller. Use this alias name in the HTML code to access the vm variable. In your example, you can change it as given below:
<div ng-app="myApp" id="posts" ng-controller="myCtrl as postsCtrl">
<li ng-repeat="post in postsCtrl.posts track by $index">
<p>{{post.data.children.data.ups}}</p>
<p>{{post.data.children.data.title}}</p>
</li>
</div>
And in the scripts tag:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($http) {
var vm = this;
vm.posts = '';
$http.get("http:/www.reddit.com/.json")
.then(function(response) {
vm.posts = response.data;
}, function(response) {
vm.posts = 'Something went wrong';
});
});
</script>

Consuming REST service using AngularJS

I have a REST Service written in Java which returns an array of data in JSON like this:
[{"key":"London","value":"51.30"}]
Now I'm trying code an AngularJS REST clients using the AJS documentation. So far I've been able to invoke the REST service (I can see from the server logs) yet nothing is printed in the HTML page.
Here is my code:
<!doctype html>
<html >
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.js"></script>
<script language="javascript">
angular.module('myApp',['ngResource']);
function Ctrl($scope,$resource) {
var Geonames = $resource(
'http://localhost:8080/rest-application/rest/json', {
}, {
query: { method: 'GET', isArray: true },
create: { method: 'POST' }
}
);
$scope.objs = Geonames.query();
};
Ctrl.$inject = ['$scope','$resource'];
</script>
</head>
<body >
<div ng-app="myApp">
<div ng-controller="Ctrl">
{{objs.key}} - {{objs.value}}
</div>
</div>
</body>
</html>
I have tried this example with several small variants taken from tutorials yet it is still not working. Any help ?
Thanks!
What you get back from query() is an array so you should loop over it with ng-repeat
<div ng-app="myApp">
<div ng-controller="Ctrl">
<ul>
<li ng-repeat="obj in objs">{{obj.key}} - {{obj.value}}</li>
</ul>
</div>
</div>
First of all, let's organize your code a bit:
var app = angular.module('myApp',['ngResource']);
// Controllers get their dependencies injected, as long as you don't minify your code and lose variable names.
app.controller('Ctrl', function($scope, $resource) {
$scope.objs = []; // We initialize the variable for the view not to break.
// For the query example, you don't need to define the method explicitly, it is already defined for you.
var Geonames = $resource('http://localhost:8080/rest-application/rest/json');
// Resource methods use promises, read more about them here: http://docs.angularjs.org/api/ng/service/$q
Geonames.query({}, function(arrayResult) {
$scope.objs = arrayResult;
});
});
You have to adjust your html code with an ng-repeat directive to handle each item of your array:
<body>
<div ng-app="myApp">
<div ng-controller="Ctrl">
<!-- object is a reference for each item in the $scope.objs array-->
<span ng-repeat="object in objs">
{{object.key}} - {{object.value}}
</span>
</div>
</div>
</body>

Resources