I am building an app (running on MAMP) that holds contact information that will expand to hold more data such as project name & deadline, once this part is functional.
When the user visits /projects.php#/project/
I would like them to see a list of all the project names with a link to their detail page.
Do I need the .json at the end?
What does the @id do?
return $resource('data/project.json/:id', {id: '@id'});
When the user visits /projects.php#/project/a-gran-goodn
I would like them to see the details about this project(for now, just the name & address).
$scope.project = $routeParams.id ? Project.get({id: $routeParams.id}): new Project();
http://plnkr.co/edit/7YPBog
This file lives on http://localhost:8888/angularjs/ProjectsManager/data/project.json
[
{ "address" : [ " 3156 Dusty Highway",
" Teaneck New Jersey 07009-6370 US"
],
"id" : "a-gran-goodn",
"name" : "Grania Goodner",
"phone" : " (862) 531-9163"
},
{ "address" : [ " 62 Red Fawn Moor",
" Rodney Village West Virginia 25911-8091 US"
],
"id" : "b-aime-defranc",
"name" : "Aimery Defranco",
"phone" : " (681) 324-9946"
}
]
var projectsApp = angular.module('projects', ['ngResource']);
projectsApp.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'ProjectListCtrl',
templateUrl: 'partials/projectlist.html'})
.when('project/:id', {
controller: 'ProjectDetailCtrl',
templateUrl: 'partials/projectdetail.html'
})
.otherwise('/');
});
projectsApp.factory('Project', function($resource) {
return $resource('data/project.json/:id', {id: '@id'});
});
projectsApp.controller('ProjectListCtrl', function(Project, $scope) {
$scope.projects = Project.query();
console.log($scope.projects);
});
projectsApp.controller('ProjectDetailCtrl', function(Project, $routeParams, $scope) {
$scope.project = $routeParams.id
? Project.get({id: $routeParams.id})
: new Project();
});
<a href="#/project/" class="btn">Add new item</a>
<ul class="unstyled">
<li ng-repeat="project in projects">
<div class="well">
<h2><small>{{project.id}}</small> {{project.name}}</h2>
<a href="#/project/{{project.id}}" class="btn btn-link">View Info for {{project.name}}</a>
</div>
</li>
</ul>
<h3>Information</h3>
<p>Name: {{project.name}}</p>
<p>Phone Number: {{project.phone}}</p>
<p ng-repeat="line in project.address">{{line}}</p>
<?php
header('Access-Control-Allow-Origin: *');
?>
<!doctype html>
<html ng-app="projects">
<head>
<meta charset="utf-8">
<title ng-bind="title" ng-cloak>Restaurant —</title>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
</head>
<body ng-controller="ProjectListCtrl">
<a class="brand" href="#">Projects Manager</a>
<div id="app-container" class="container-fluid">
<div class="row-fluid">
<div class="span12" id="main" ng-view>
</div><!--/.span12-->
</div><!--/.row-fluid-->
<footer>Copyright Projects © 2013</footer>
</div><!--/.container-->
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<!-- Don't forget to load angularjs AND angular-resource.js -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular-resource.js></script>
<!--Controllers-->
<script src="app.js"></script>
</body>
</html>
Since you can't query against a raw JSON file like you can with RESTful-style URLs (which is what $resource
is built to do), you can instead get a copy of the JSON and then build your own query
, get
, etc. that looks at the data and returns the right thing. It's a bit tricky because you also want to support new Project
, which doesn't really make sense when using a file-backed store, but this example supports it:
projectsApp.factory('Project', function($http) {
// Create an internal promise that resolves to the data inside project.json;
// we'll use this promise in our own API to get the data we need.
var json = $http.get('project.json').then(function(response) {
return response.data;
});
// A basic JavaScript constructor to create new projects;
// passed in data gets copied directly to the object.
// (This is not the best design, but works for this demo.)
var Project = function(data) {
if (data) angular.copy(data, this);
};
// The query function returns an promise that resolves to
// an array of Projects, one for each in the JSON.
Project.query = function() {
return json.then(function(data) {
return data.map(function(project) {
return new Project(project);
});
})
};
// The get function returns a promise that resolves to a
// specific project, found by ID. We find it by looping
// over all of them and checking to see if the IDs match.
Project.get = function(id) {
return json.then(function(data) {
var result = null;
angular.forEach(data, function(project) {
if (project.id == id) result = new Project(project);
});
return result;
})
};
// Finally, the factory itself returns the entire
// Project constructor (which has `query` and `get` attached).
return Project;
});
You can use the results of query
and get
like any other promise:
projectsApp.controller('ProjectListCtrl', function(Project, $scope) {
$scope.projects = Project.query();
});
projectsApp.controller('ProjectDetailCtrl', function(Project, $routeParams, $scope) {
$scope.project = $routeParams.id
? Project.get($routeParams.id)
: new Project();
});
Note the change to Project.get($routeParams.id)
; also, the updated Plunker also fixes a problem in your $routeProvider
configuration.
This is all demonstrated here: http://plnkr.co/edit/mzQhGg?p=preview
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With