I am learning AngularJS through the book "Learning Web Development with Bootstrap and Angularjs” by Stephen Radford.
There is a single “Contacts Manager” project which is developed in it throughout the chapters with the help of angularJS and a bit of Bootstrap.
In Chapter 8 “Connecting to the Server”, you are taught various ways on how to communicate with a server, mainly by using the ngResource module which exposes the $resource service, which we then inject into our created factory service (named ‘Contact’) and include a method in it to establish our connection.
.factory('Contact', function ContactFactory($resource) {
var Resource = $resource("http://localhost:3000/contactList.json", {id: "@id"},{ update: {method: "PUT"} });
return {
get: function() {
return Resource.query();
},
find: function(id) {
return Resource.get({id: id});
},
create: function() {
return new Resource();
},
destroy: function(id) {
Resource.remove({id: id});
}
};
})
The idea is that on the main page you get displayed a list of contacts. The $resource service did a great job at retrieving the contacts from the json file when I have requested that in the controller for that page with the Contact.get() method and with the use of ng-repeat display it as an individual contact.
(...)
<tr ng-repeat="contact in contacts | filter:search">
<td>{{contact.name}}</td>
<td>{{contact.email}}</td>
<td>{{contact.phone}}</td>
<td><a href="#/contact/{{contact.id}}" class="btn btn-success btn-xs">View</a>
<button class="btn btn-danger btn-xs" ng-click="delete($index)">Delete</button>
When i click on the "view" button to view an individual contact the ng-route $routeProvider service is used. Here is an excerpt for the individual contact view:
$routeProvider
.when('/contact/:id', {
controller: 'contactCtrl',
templateUrl: 'assets/partials/contact.html'
})
.otherwise({
redirectTo: '/'
});
})
The view is populated with the "contact.html" partial and the controller assigned to it in this case is 'contactCtrl'.
.controller('contactCtrl', function($scope, $routeParams, Contact) {
$scope.contact = Contact.find();
})
This is where the problem starts. The find method requests an id argument to be provided. The page does not display any data even if I simply hardcode an id number into it.
Is the problem in the definition of the find() method then?
*Each field in the 'contact.html' partial requests a particular property value from 'contact' to display, for example:
<p class="form-control-static" id="name" editable="contact.name" field-type="text"></p>
("editable" is just a custom directive that makes the field editable.)
*Here is the JSON I have been using:
[{
"id": "0",
"name":"John Doe",
"phone":"08154335882",
"address":"12 Bronton street, Leicester",
"website":"http://www.Johnthedoe.co.uk",
"email":"john@example.com",
"notes":"An ordinary person needing more attention."
},
{
"id": "1",
"name":"Karan Bromwich",
"phone":"09875681235",
"address":"3 Wiltshire Abbey Road, Manchester",
"website":"http://www.wearelost.com",
"email":"karan@email.com",
"notes":"A new client of ours."
}
]
UPDATE: If i pass $routeParams.id into the Contact.get() method it displays the following error:
Error in resource configuration for action get
. Expected response to contain an object but got an array (Request: GET http://localhost:3000/contactList.json")
So I modify the JSON file by removing the square brackets and make it an object. It then throws an error with an "unexpected ," which is basically saying there can only be one entry in the JSON file. When I leave only one entry it finally displays the information, however the main page expects an array in the JSON file so it throws an error there instead.
So the question is: how is it possible to get data from a single object in this JSON file using get() without having this error thrown?
Error in resource configuration for action get
. Expected response to contain an object but got an array (Request: GET http://localhost:3000/contactList.json)
UPDATE:
I 've found sort of a solution to request the necessary JSON object. Make sure that the second parameter of the $resource service has isArray property set to true on "get" and "query", so that the line looks like:
var Resource = $resource("http://localhost:3000/contactList.json", {id: "@id"},
{ 'get': {method: "GET", isArray: true },
'update': {method: "PUT", isArray: true},
'query': {method: "GET", isArray: true}
});
Which makes the $resource service expect an array, as the property suggests. If I provide an index to the object, so that in my example it would be:
<p class="form-control-static" id="name" editable="contact[0].name" field-type="text"></p>
It'll display the correct data. But that kills the purpose of the find() method. I suspect that the JSON structure that I have created is simply wrong.
Is anyone able to suggest how to have a JSON file containing multiple objects that one could refer to by their specific property values(for example, by the id property that the object has)?