why can't I access data within this ng-repeat? - javascript

I made the below code to learn Angular. It uses the input entered by user to make an ajax request for a json file that contains a list of object, then print that list to the user.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script type="text/javascript">
angular.module('myApp', [])
.controller('myController', function($http) {
var ctlr = this;
ctlr.param = "";
ctlr.responses = [];
this.makeQuery = function() {
$http.get('http://localhost:8080?p=' + ctlr.param))
.then(function(data) {
ctlr.response = data; // data -> [{key1: value1,...},...]
});
};
});
</script>
</head>
<body ng-app="myApp">
<div ng-controller="myController as mc">
<input type="text" ng-model="mc.param">
<input type="submit" ng-click="mc.makeQuery()" value="Submit">
<ul>
<li ng-repeat="res in responses">
<span>{{res.key1}}, {{res.key2}}</span>
</li>
</ul>
</div>
</body>
</html>
When I run this code in Chrome, I see a list of empty bullet points. Chrome DevTools shows the json file returned as expected so I know ctlr.param works. However the list has empty bullet points so ng-repeat does not work correctly. It seems I cannot access cltr.responses properly. Does anyone know why?

Your responses object is binded to this and not to $scope as you are using controller as
You should use mc.responses instead of responses
<li ng-repeat="res in mc.responses">
<span>{{res.key1}}, {{res.key2}}</span>
</li>
You can read more from johnpapa style

Above solution is right but as i checked the complete code and found that there is one mistake.
In script code
ctlr.response = data; // data -> [{key1: value1,...},...] should be
ctlr.responses = data; // data -> [{key1: value1,...},...]

Related

Nothing Displayed in web page with Angular clearly showing data in an array

Not sure what is going on , but I'm not getting anything to display on my web page with ng-repeat with template.
Here is a picture image showing the data
This pic shows my console.log output with array of objects
NO IDEA why doesn't just display on the web page!
Devices: Array[17]
0 : Object
Aid : "....."
...
1 : Object
Angular controller with function
(function () {
'use strict';
angular.module('app').controller('DeviceController', DeviceController);
function DeviceController($http){
var vm = this;
var dataService = $http;
//dataService.get("/api/Product")
vm.devices = [];
deviceList();
function deviceList() {
dataService.get("http://localhost:42822/api/device")
.then(function (result) {
vm.devices = result.data;
//debugger;
console.log(vm.devices);
},
function (error) {
handleException(error);
});
}
function handleException(error) {
alert(error.data.ExceptionMessage);
}
}
})();
HTML
<html>
<head> </head>
<body>
<div ng-app="app" ng-controller="DeviceController as vm">
<div>test</div><br>
<table>
<tbody>
<tr ng-repeat="device in vm.devices">
<td>{{device.Aid}}</td>
<td>{{device.DeviceId}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<!--<script src="~/Scripts/angular.min.js"></script>-->
<script src="./app/app.module.js"></script>
<script src="./app/device.controller.js"></script>
</html>
NO IDEA why doesn't just display on the web page!
As you have data inside Devices object of response, then you need to change your assignment in ajax resolve like below.
vm.devices = result.data.Devices;
I'd suggest you to change your response from server, instead of sending Devices collection in Devices object, directly send it in response.
OR you could also make changes on HTML directly, but it wouldn't be good way to go.
<tr ng-repeat="device in vm.devices.Devices">
<td>{{device.Aid}}</td>
<td>{{device.DeviceId}}</td>
</tr>

how to show data from Json file in correct way with AngularJS

I need to get the data from a json file below(please click the "Json File" link to see how is that structure of Json file) but i am confused what should I put after "$Scope.listOfRecipe=", I put response.data.recipes, but it doesn't work here and there are some error .
angular.js:12520 TypeError: Cannot read property 'recipes' of undefined
at recipesController.js:10
at angular.js:10296
at angular.js:14792
at r.$eval (angular.js:16052)
at r.$digest (angular.js:15870)
at r.$apply (angular.js:16160)
at g (angular.js:10589)
at T (angular.js:10787)
at XMLHttpRequest.w.onload (angular.js:10728)
Json File here is my json file
This is my recipesControllers.js
var myApp = angular.module('myApp', []);
myApp.controller('namesCtrl',function ($scope, $http) {
$scope.listOfRecipe = null;
$http.get('http://164.132.196.117/chop_dev/recipe/recipes.json')
.success(function (response) {
$scope.listOfRecipe = response.data.recipes;
})
});
This is my Index.html
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<ul>
<li ng-repeat="x in listOfRecipe ">
{{ x.Recipe.id + ', ' + x.Recipe.name }}
</li>
</ul>
</div>
<script src="C:/Users/Enetfirm Server/Desktop/AngularJs/recipesController.js"></script>
</body>
</html>
You can console.log(response) and see what the response is and adjust your code accordingly.
But I would recommend using the standard promise pattern:
$http.get('http://164.132.196.117/chop_dev/recipe/recipes.json')
.then(function(resp) {
$scope.listOfRecipe = resp.data.recipes;
})
.catch(function(errResp) {
// catch error
})
.finally(function() {
// when it is done do something in the view
// remove a spinner gif or scroll to top ...
});
Can you verify the file is downloading on the developer tools - network tab ?
Make sure it's working, and please console.log response and response.data in order to verify its there !
It's a Json file means the response is the Json it self and not res.data
Please check it and reply for sharing your solution

Angular.js - Convert string with special characters and numbers into Array and display with ng-repeat

I am new to angular.js and I'm having an issue with converting string into array and displaying it with ng-repeat, so far i got this custom filter from a stackoverflow question and the codes are:
JS:
var app = angular.module('globalModule', [])
app.controller("SampleController", function($scope){
$scope.data = "123abc123";
});
app.filter("spaceBreak",
function () {
return function ( value ) {
if( !value.length ) return;
return value.split("");
}
});
HTML:
<body ng-controller="SampleController">
<h4 id="id_{{$index}}" ng-repeat="value in data | spaceBreak"><span ng-bind="value"></span></h4>
</body>
My problem is, it converts and display properly if it is an alphabet(abc) or a number(123) alone, and if combined (abc123) or (123abc) still good, but if the data is number+alphabet+number (123abc123) it doesnt show anymore in ng-repeat. I am really lost and really need help. Hope someone can lend me an answer.
I think what you are looking for is the track by $index functionality. You code errors out because you have duplicates in your $scope.data. That filter isn't really doing anything for you, so you can just ng-repeat through your $scope.data string.
var app = angular.module('globalModule', [])
app.controller("SampleController", function($scope){
$scope.data = "123abc123";
})
<!DOCTYPE html>
<html ng-app="globalModule">
<head>
<script data-require="angular.js#1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="SampleController">
<h4 id="id_{{$index}}" ng-repeat="value in data track by $index"><span ng-bind="value"></span></h4>
</body>
</html>

Use Coldfusion query resultset in AngularJS

I'm trying to use AngularJS in my cfm files to display data from cfquery resultset.
I used below code in my cfm file.I'm not able to see any output.
P.S. I'm really new to AngularJS. So if anyone can please help me out here it would be great.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html ng-app="Demo">
<head>
<link rel="stylesheet" href="/Applications/_Common/style.css" type="text/css">
</head>
<body>
<cfsetting enablecfoutputonly="Yes">
<CF_GetProjectData project_number=349246 query_name="GetProject">
<div ng-controller="DemoController">
<div ng-repeat="number in project">
{{number.project_number}} - {{number.project_name}}
</div>
<!-- <input name="imprint" type="text" size="10" ng-model="first">
<p>{{first}}</p> -->
</div>
<cfoutput>
<script language="JavaScript" src="/CFIDE/scripts/wddx.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script language="text/javascript">
var theProjectArray; < cfwddx action = "CFML2JS"
input = "#GetProject#"
toplevelvariable = "theProjectArray" >
</script>
<script>
var Demo = angular.module("Demo", []);
Demo.controller("DemoController", function($scope) {
$scope.project = theProjectArray;
alert(theProjectArray);
});
</script>
</cfoutput>
<cfsetting enablecfoutputonly="No">
</body>
</html>
I am not sure about Angular.js but based on the code you have posted, it seems, you need to wrap ng-controller div in cfoutput. This is because you have set enablecfoutputonly="Yes". So only the content inside cfoutput will be rendered.
I'm a CF developer that's currently learning Angular as well. First of all Angular is a MVC framework and will work for you best of you follow the rules of Separation of Concern (SoC). I know unless you are using Object Relational Mapping (ORM) in CF this is counter intuitive but it will save you so much hassle and trouble shooting later.
For your problem right now though i would
combine both script blocks.
your variable theProjectArray is defined with var so it's not
global. Are you sure it's making it into your controller?
the line toplevelvariable = "theProjectArray" > ... is the greater
than sign a type-o?
After you've done those i would console.log(theProjectArray); right after it's defined. Then console.log(theProjectArray); again in your controller to ensure it's getting passed in properly.
Just for your reference here is a very basic example of a controller and a factory in angular calling a CFC. Since i've been doing things this way the only time i use ColdFusion is to retrieve data and model it. It's simplified my code and logic quite a bit and has allowed me to do a lot more now that i'm not leaning on ColdFusion.
var myapp = angular.module("test.myapp", [])
myapp.controller("MyController", function($scope, getevent) {
$scope.myData = {};
$scope.myData.doUpdate = function(item, event) {
getevent.GetProgram(item).success(function(data, status, headers, config) {
console.log(data.DATA);
$scope.test = data.DATA;
$scope.test.DATE = new Date(data.DATA.DATESTART);
});
getevent.GetProgram(item).error(function(data, status, headers, config) {
console.log("FAILED: "+item);
alert("AJAX failed!");
});
}
});
myapp.factory('getevent', function($http){
return {
GetProgram: function(item) {
var programInfo = '/foundation/cfc/calendar.cfc?method=getevent&eventid='+item;
return $http.get(programInfo);
}
};
});

Angular $scope not showing correct data in HTML

I have a cordova app in which I want to show the details of a location. For some reason when I try to display a variable in HTMl which is being successfully assigned in JS, nothing appears.
JS controller:
app.controller('placeCtrl', function($scope, LocDat){
LocDat.async().then(function(d){
$scope.item= places.selectedItem;
$scope.locs = [];
for(var i=0; i<d.length; i++){
if(d[i].attributes.Joint.id === places.selectedItem.id){
getDistance(d[i]);
$scope.locs.push(d[i]);
}
}
$scope.showSite = function(){
//var ref = navigator.app.loadUrl($scope.item.attributes.Website, '_blank');
var ref = window.open($scope.item.attributes.Website,'_blank','location=yes');
}
$scope.showDetail = function(index){
var selectedItem = d[index];
d.selectedItem = selectedItem
$scope.l = selectedItem;
console.log($scope.l.attributes.City);
$scope.ons.navigator.pushPage('location_detail.html', { title : d.selectedItem.attributes.Address });
}
});
HTML:
<!DOCTYPE html>
<html>
<body>
<div ng-controller="placeCtrl">
<ons-page class="center" ng-device-backbutton="myNavigator.popPage()">
<ons-toolbar>
<div class="left"><ons-back-button ons-if-platform="ios">Back</ons-back-button></div>
<div id="title" class="center">{{l.attributes.City}}, {{l.attributes.State}}</div>
<!--<div class="left" onclick=".myNavigator.popPage()"><ons-back-button>Back</ons-back-button></div>-->
<!--<div class="center">Page 2</div>-->
</ons-toolbar>
<h2 align="center">Location Details Go Here</h2>
<!--enter more content here-->
</ons-page>
</div>
</body>
</html>
Image of the Console output:
Apparently my reputation is too low to post images... Seriously? Anyway, it displays the City name in the console successfully, but the html only shows the comma
Services that make async calls, such as your LocDat, do not automagically trigger a digest event when they return. If you're writing a service it should call a $scope.$apply() chained to the end of the promise. Alternatively you can wrap any changes to $scope variables in an apply and that should get you where you need.
$scope.$apply( function() { $scope.l = selectedItem; } );
In angularjs data binding, if the data type is list or object, it will pass by reference value in view.
When you do like $scope.l = selectedItem, the reference is changed, but the watched reference is previous one. So it will be always better to bind by an attribute on an object, but not the object itself. like:
<div id="title" class="center">{{obj.l.attributes.City}}, {{obj.l.attributes.State}}</div>
And update in controller with:
$scope.obj.l = selectedItem;
The issue was that the scope changed when I loaded the new page. I'm now passing the data through the parameters of onsenui's pushpage function and assigning them to the scope variables in a separate controller.

Categories

Resources