title: angularjs, java, 404, spark
body: <p>I'm trying to learn more about creating SPA's using AngularJS and Java. I followed the tutorial <a href="https://blog.openshift.com/developing-single-page-web-applications-using-java-8-spark-mongodb-and-angularjs/" rel="nofollow noreferrer">here</a> and i managed to get it working except for one bug. When i create a new todo and then return to the todo list i get the following error. </p>
  
  <blockquote>
    <p>angular.js:8109 POST <a href="http://localhost:8080/api/v1/todos" rel="nofollow noreferrer">http://localhost:8080/api/v1/todos</a> 404 (Not Found)</p>
  </blockquote>
  
  <p>The console output is as follows</p>
  
  <pre><code>HEJ ERROR
  app.js:51 Error createTodo &lt;html&gt;
  &lt;head&gt;
  &lt;meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/&gt;
  &lt;title&gt;Error 404 &lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;h2&gt;HTTP ERROR: 404&lt;/h2&gt;
  &lt;p&gt;Problem accessing /api/v1/todos. Reason:
  &lt;pre&gt;    Not Found&lt;/pre&gt;&lt;/p&gt;
  &lt;hr /&gt;&lt;i&gt;&lt;small&gt;Powered by Jetty://&lt;/small&gt;&lt;/i&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Why doesn't it work after i added another todo?</p>
  
  <p>Angular code</p>
  
  <pre><code>var app = angular.module('todoapp', [
      'ngCookies',
      'ngResource',
      'ngSanitize',
      'ngRoute'
  ]);
  
  app.config(function ($routeProvider) {
      $routeProvider.when('/', {
          templateUrl: 'views/list.html',
          controller: 'ListCtrl'
      }).when('/create', {
          templateUrl: 'views/create.html',
          controller: 'CreateCtrl'
      }).otherwise({
          redirectTo: '/'
      })
  });
  
  app.controller('ListCtrl', function ($scope, $http) {
      $http.get('/api/v1/todos').success(function (data) {
          $scope.todos = data;
      }).error(function (data, status) {
          console.log('Error listctrl ' + data)
      })
  
      $scope.todoStatusChanged = function (todo) {
          console.log(todo);
          $http.put('/api/v1/todos/' + todo.id, todo).success(function (data) {
              console.log('status changed');
          }).error(function (data, status) {
              console.log('Error todostatuschanged' + data)
          })
      }
  });
  
  app.controller('CreateCtrl', function ($scope, $http, $location) {
      $scope.todo = {
          done: false
      };
  
      $scope.createTodo = function () {
          console.log($scope.todo);
          $http.post('/api/v1/todos', $scope.todo, $location).success(function (data) {
              console.log("HEJ")
              $location.path('/');
          }).error(function (data, status) {
              console.log("HEJ ERROR")
              console.log('Error createTodo ' + data)
          })
      }
  });
  </code></pre>
  
  <p>Java Code:</p>
  
  <pre><code>import static spark.Spark.get;
  import static spark.Spark.post;
  import static spark.Spark.put;
  
  public class TodoResource {
  
      private static final String API_CONTEXT = "/api/v1";
  
      private final TodoService todoService;
  
      public TodoResource(TodoService todoService) {
          this.todoService = todoService;
          setupEndpoints();
      }
  
      private void setupEndpoints() {
          post(API_CONTEXT + "/todos", "application/json", (request, response) -&gt; {
              todoService.createNewTodo(request.body());
              response.status(201);
              return response;
          }, new JsonTransformer());
  
          get(API_CONTEXT + "/todos/:id", "application/json", (request, response)
  
                  -&gt; todoService.find(request.params(":id")), new JsonTransformer());
  
          get(API_CONTEXT + "/todos", "application/json", (request, response)
  
                  -&gt; todoService.findALL(), new JsonTransformer());
  
          put(API_CONTEXT + "/todos/:id", "application/json", (request, response)
  
                  -&gt; todoService.update(request.params(":id"), request.body()), new JsonTransformer());
      }
  
  
  }
  </code></pre>