4

Overview

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.

Questions

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.

  1. How should I write the following to access all of my data?

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).

  1. How should I write the following to return my data by Id? $scope.project = $routeParams.id ? Project.get({id: $routeParams.id}): new Project();

plunkr file

http://plnkr.co/edit/7YPBog

project.json

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"
}
]

app.js

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();
});

partials/projectlist.html

<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>

partials/projectdetails.html

<h3>Information</h3>
<p>Name: {{project.name}}</p>
<p>Phone Number: {{project.phone}}</p>
<p ng-repeat="line in project.address">{{line}}</p>

index.php

<?php
header('Access-Control-Allow-Origin: *');
?>
<!doctype html>
<html ng-app="projects">
  <head>
    <meta charset="utf-8">
    <title ng-bind="title" ng-cloak>Restaurant &mdash;</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 &copy; 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>
6
  • Are you accessing the JSON file directly, or going through some server that exposes RESTful URLs? $resource is designed to work with RESTful-style URLs, it's probably not the best choice for a plain, flat file. Commented Jul 5, 2013 at 18:38
  • @BrandonTilley For testing purposes, I have it as a flat json file but I will eventually convert it to a sqlite database on LAMP server. What would be the approach if I just kept it as a flat file though? Commented Jul 5, 2013 at 18:43
  • I would probably just use $http to fetch the entire file, and then use JavaScript code on the client-side to do any necessary "querying." Of course this may only work well until the JSON reaches a certain size. Commented Jul 5, 2013 at 18:53
  • You really should put all of this in a plunkr. Commented Jul 5, 2013 at 19:10
  • @JamesKleeh I just added that to my post. Commented Jul 5, 2013 at 19:51

2 Answers 2

10

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

Sign up to request clarification or add additional context in comments.

Comments

2

i will paste here a generic code i use to fetch json from your local or a remoteserver maybe it will help you:

it uses a factory that you can call when you need it.

app.factory('jsonFactory', function($http) {  
  var jsonFactory= {      
    fromServer: function() {        
        var url = 'http://example.com/json.json';
            var promise = $http.jsonp(url).then(function (response) {
          return response.data;
        });      
      return promise;
    },
    hospitals: function() {     
        var url = 'jsons/hospitals.js';               
            var promise = $http.get(url).then(function (response) {
          return response.data;
        });      
      return promise;
    }        
    };
  return jsonFactory;
});

Then when you need to call it:

function cardinalCtrl(jsonFactory, $scope, $filter, $routeParams) {
   jsonFactory.hospitals().then(function(d){
        $scope.hospitals=d.hospitals;
   });
   jsonFactory.fromServer().then(function(d){
        $scope.fromServer=d.hospitals;
   });

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.