AngularJS Binding doesn't seem to work - javascript

I'm fairly new to Angular, and a simple binding doesn't work for me.
It just shows me {{ trip.name }} and {{trip.created}} just as they're written.
My controller:
(function () {
"use strict";
angular.module("app-trips")
.controller("tripsController", tripsController);
function tripsController() {
var vm = this;
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created = new Date()
}];
A part of my class:
#section Scripts {
<script src="~/lib/angular/angular.min.js"></script>
<script src="~/js/app-trips.js"></script>
<script src="~/js/tripsController.js"></script>
}
<div class="row" ng-app="app-trips">
<div ng-controller="tripsController as vm" class="col-md-6 col-md-offset-3">
<table class="table table-responsive table-striped">
<tr ng-repeat="trip in vm.trips">
<td>{{ trip.name }}</td>
<td>{{ trip.created }}</td>
</tr>
</table>
</div>
the view of the controller:
(function () {
"use strict";
angular.module("app-trips", ['ngSanitize']);
})();
BTW - supposedly according to the course I'm following, I don't need ['ngSanitize'] yet, but without it it doesn't even show the DIVs.
EDIT: as #jellyraptor noticed , I had a typo with = instead of :
EDIT 2 :
It was the typo + the [ngSanitize] which I really didn't needed. I fixed the typo and passed an empty array and everything works. Thanks all

Either Angular isn't loading or it is encountering an error. Bring up the dev tools with F12 and see if there are errors in the console. Also in the console, you can type 'angular' and hit enter and if it reports that angular is undefined then angular is not loading properly.

Because you are using controllerAs syntax and here the variable is vm. so for access scope object use vm instead of tripsController
<tr ng-repeat="trip in vm.trips">
<td>{{ trip.name }}</td>
<td>{{ trip.created }}</td>
</tr>
(function() {
"use strict";
angular.module("app-trips", []);
})();
angular.module("app-trips")
.controller("tripsController", tripsController);
function tripsController() {
var vm = this;
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created: new Date()
}];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.min.js"></script>
<div ng-app="app-trips" ng-controller="tripsController as vm" class="col-md-6 col-md-offset-3">
<table class="table table-responsive table-striped">
<tr ng-repeat="trip in vm.trips">
<td>{{ trip.name }}</td>
<td>{{ trip.created }}</td>
</tr>
</table>
</div>

You put an equals sign in your trips array's second object's 'created' attribute.
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created = new Date()
}];
should be
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created: new Date()
}];

Related

Can't display in console log a Angular object value with controller

I'm beginner in AngularJS and so I try to learn this framework.
To train, I use a REST API with Star Wars data (https://swapi.co/).
I have a problem : i can't display a value of object in console log.
See my Angular JS code :
var pokeApp = angular.module('pokedex', ['ngResource']);
pokeApp.config(['$resourceProvider', function($resourceProvider) {
$resourceProvider.defaults.stripTrailingSlashes = false;
}]);
pokeApp.controller('PokeController', function ($scope,$log, People) {
$scope.people = null;
$scope.getPeople = function(idPeople) {
$myPeople = People.get({id:idPeople});
$log.log($myPeople.name); // result in console : undefined
$scope.people = $myPeople;
$log.log($scope.people.name); // result in console : undefined
};
});
pokeApp.service('People', function($resource)
{
$jsonPeople = $resource('https://swapi.co/api/people/:id', {id:'#id'});
return $jsonPeople;
});
And see my HTML code :
<body ng-app="pokedex">
<div class="container" ng-controller="PokeController">
<h1>Star Wars Engine</h1>
<div>
<input ng-model="idPeople"/>
<button ng-click="getPeople(idPeople)">Search</button>
</div>
<br />
<div>
<table border="1" class="tableSW">
<tr>
<th>Nom</th>
<th>Sexe</th>
<th>Taille</th>
<th>Poids</th>
<th>Date de naissance</th>
<th>Couleur de peau</th>
</tr>
<tr>
<td>{{ people.name }}</td>
<td>{{ people.gender }}</td>
<td>{{ people.height }}</td>
<td>{{ people.mass }}</td>
<td>{{ people.birth_year }}</td>
<td>{{ people.skin_color }}</td>
</tr>
</table>
</div>
</div>
<!-- Dependencies -->
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/angular-resource.min.js"></script>
<script src="js/pokedex.js"></script>
<style>
.tableSW td{
width: 150px;
}
.tableSW th{
width: 150px;
}
</style>
</body>
When i try to display value of my object from API in the console, it contains "undefined".
I don't understand why, can you explain me ?
I specify the display of informations in the view works very well.
Thanks a lot.
Simon.
For information, I can display the json of the object in the console ($log.log($myPeople)) :
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.co/api/planets/1/",
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/6/",
"https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/",
"https://swapi.co/api/films/7/"
],
"species": [
"https://swapi.co/api/species/1/"
],
"vehicles": [
"https://swapi.co/api/vehicles/14/",
"https://swapi.co/api/vehicles/30/"
],
"starships": [
"https://swapi.co/api/starships/12/",
"https://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.co/api/people/1/"
}
But, it's impossible to display the name of other attribute of this object ...
$log.log($myPeople.name) returns "undefined" in console
The $resource service performs an asynchronous HTTP call. It doesn't return your data right away, instead it returns an empty object. A callback function should be passed as the second argument and it will be called when your data is available. Something like this should work.
$scope.getPeople = function(idPeople) {
$myPeople = People.get({id:idPeople}, function() {
$log.log($myPeople.name); // result in console : undefined
$scope.people = $myPeople;
$log.log($scope.people.name); // result in console : undefined
});
};
You should review the documentation on $resource on the angularjs website.
https://docs.angularjs.org/api/ngResource/service/$resource

Getting related array element AngularJS

I have a php api that returns a list of companies and a list of users,
Each user has a company_id assigned.
(Users : CustomerList) (Companies : CompanyList)
The companies have a company_id and company_name value.
I'm using resolve to get both these arrays.
When displaying the CustomerList, the company_id of the customer is displayed and everything is working fine.
But what i require is instead of the company_id being shown, I need the company_name being displayed in the CustomerList.
The company_id of the CustomerList is related to the id in the CompanyList.
Just that the company_name is contained in the companyList and not in the CustomerList. But the ID's are related and contained in the userList.
I need to get the company_name of the id that's in CustomerList and display it in the view.
resolve: { userList:function($http,$stateParams){
return $http.post('/api/get_users.php',{role:$stateParams.role},{headers: { 'Content-Type': 'application/x-www-form-urlencoded' }})
.then(function(response){
console.log(response);
return response.data.data;
})
},
companyList:function($http,$stateParams){
return $http.get('/api/get_companies.php')
.then(function(response){
console.log(response);
return response.data.data;
})
}
}
controller("CustomerList", function($scope,$location,$http,$stateParams,userList,companyList){
$scope.customers = userList;
$scope.companies = companyList;
})
VIEW
<table>
<thead>
<tr>
<th>Username</th>
<th>Company Name</th>
<th>Contact Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="customer in customers">
<td>{{ customer.username }}</td>
<td>{{ customer.company_id }}</td>
<td>{{ customer.contact_name }}</td>
</tr>
</tbody>
</table>
the customer.company_id is related to the ID in the companyList , i need to return the companyList.company_name instead of showing the company ID in the customers.
Thanks in advance for any help.
You need to join them.
So you need to create a new object with will contain the username, contact_name, company_name and other properties you need. You need to use the map() which will return an array of new objects. With username and contract_name it is easy, just assign the properties to the new created object. With company_name, we need to find the appropriete company and assign it's name to the newly created object.
Working Example with simple data, which joins two arrays based on the id.
var app = angular.module('app', []);
app.controller('ctrl', ['$scope', function($scope){
var userList = [
{username: 'A user', contact_name: 'A contract', company_id: 1},
{username: 'B user', contact_name: 'B contract', company_id: 2},
{username: 'C user', contact_name: 'C contract', company_id: 3},
];
var companyList = [
{id: 1, name: 'A Company'},
{id: 2, name: 'B Company'},
{id: 3, name: 'C Company'},
];
$scope.customers = userList.map(item => {
var foundCompany = companyList.find(company => company.id === item.company_id);
return {
username: item.username,
contact_name: item.contact_name,
company_name: foundCompany ? foundCompany.name : ''
};
});
$scope.companies = companyList;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="ctrl">
<table>
<thead>
<tr>
<th>Username</th>
<th>Company Name</th>
<th>Contact Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="customer in customers">
<td>{{ customer.username }}</td>
<td>{{ customer.company_name }}</td>
<td>{{ customer.contact_name }}</td>
</tr>
</tbody>
</table>
</body>
You can structure your companies list in such a way that each object in list is key value pair with key being id of company and value being complete object of company details and then access it easily.
eg
$scope.companies = {
{
"companyId1" : {
"name" : "companyName",
"field2" : "vlue2"
}
},
{
"companyId2" : {
"name" : "companyName2",
"field2" : "vlue2"
}
}
}
and then in your html access it using
{{companies[customer.company_id].name}}
This will work for you
map your userList so that it will contain companyName
var mappedCustomerList= userList.map(function(user){
var user=userWithCompanyName;
userWithCompanyName['companyName']=
companyList[companyList.findIndex(function(company){return company['id']==user['company_id']})].companyName;
return userWithCompanyName;
});
$scope.customerList=mappedCustomerList;
so then from your view you can access companyName
<td>{{customer.companyName}}</td>

angular ng-repeat needs changes in data that is obtained from json

I have a JSON object that does not have proper data. So i want to replace the obtained value with one from a lookup table, but I'm not sure how to replace the value of the data corresponding to the lookup table.
lookupTable = {
"pizza": function() {
console.log("food");
},
"house": function() {
console.log("building");
},
"air": function() {
console.log("nothing");
}
};
$scope.value =lookupTable["pizza"]()
my html file has
<tr ng-repeat="x in names">
<td>{{ x.lookupTable["pizza"]() }}</td>
My code is at http://plnkr.co/edit/w4lOFVRo9vSi8vqfbpXV?p=preview
Any help is appreciated!
Here are some problems in your code from the link you provided:
Functions on the lookupTable is not returning anything as pointed out in the previous answers.
lookupTable is not a property of $scope.names so using x.lookupTable is invalid.
To make it work, you should:
The functions from lookupTable should return the actual values instead of using console.log
Bind lookupTable to $scope
Use lookupTable directly inside the view as it is bound to $scope
Here is the relevant code:
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name]() }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
$scope.lookupTable = {
"pizza": function() {
return 'food';
},
"house": function() {
return 'building';
},
"air": function() {
return "nothing";
}
};
});
</script>
Your code is very confused. I tried to edit your plunker, maybe is easier to see that to explain.
<!DOCTYPE html>
<html>
<scriptsrc="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name] }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
lookupTable = {
"pizza": "food",
"house": "building",
"air": "nothing"
};
$scope.lookupTable = lookupTable;
$scope.value = lookupTable["pizza"]
console.log(lookupTable["house"])
});
</script>
Looking at your code, I am not sure what you want to achieve.
The ng-repeat gives you three objects out of names, but none of them has a lookupTable member, so {{ x.lookupTable["pizza"] }} fails silently.
You can make it visible, if you just bind to {{ x }}

AngularJS ng-show not firing when used with map

Trying to use a key/value map to determine if an angular controlled element should be displayed :
http://jsfiddle.net/9fR23/181/
But I receive a exception :
angular.js:6173 TypeError: fnPtr is not a function
at Object.elementFns [as get] (angular.js:6802)
at Object.$get.Scope.$digest (angular.js:8563)
at Object.$get.Scope.$apply (angular.js:8771)
at angular.js:986
at Object.invoke (angular.js:2873)
Using scope in this way is not illegal ? How to use a key/value map to determine if element should be displayed ? This map will be updated at runtime, so to ensure this update is reflected on UI I need to include apply() method ?
fiddle code :
<div ng-app="myapp" ng-controller="FirstCtrl">
<table class="table table-striped">
<tr ng-repeat="person in people">
<td ng-show="errorMap('1')">{{ person.first + ' ' + person.last }}</td>
</tr>
</table>
</div>
var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
var errorMap = new Object()
errorMap['1'] = 'true'
errorMap['2'] = 'false';
$scope.errorMap = errorMap
$scope.people = [
{ id: 1, first: 'John', last: 'Rambo' },
{ id: 2, first: 'Rocky', last: 'Balboa' },
{ id: 3, first: 'John', last: 'Kimble' },
{ id: 4, first: 'Ben', last: 'Richards' }
];
});
errorMap('1') is not a function, its an object. so you can do this:
ng-show="errorMap['1']"
You are trying to call a method on your scope that is called errorMap.
Use square brackets to access it.
<div ng-app="myapp" ng-controller="FirstCtrl">
<table class="table table-striped">
<tr ng-repeat="person in people">
<td ng-show="errorMap['1']">{{ person.first + ' ' + person.last }}</td>
</tr>
</table>
</div>

VueJS Resource plugin example

I am attempting to display a JSON response from PHP. I was pointed in the direction of the VueJS resource plugin. Unfortunately, the examples it gives are vague at best.
Is anyone able to provide a simple example of how to display the return JSON object in a list?
HTML:
<table id="list-items">
<tr v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</table>
JS:
new Vue({
el: '#list-items',
data: {
items: []
},
ready: function() {
this.items = this.getItems();
},
methods: {
getItems: function() {
this.$http.get('items.php', function(data){
this.items = data;
});
}
}
});
items.php must return a JSON encoded array like this:
[{id: 1, name: 'foo'},{id: 2, name: 'bar'}]
In vue 1.0.1 you can use v-for instead of v-repeat like this:
<table id="list-items">
<tr v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</table>
I think you are looking for
{{ $data | json }}

Categories