0

I'm rather new to web development and I am trying to get a better understanding of servers and databases and what the limitations are of client-side development.

Right now, I'm learning AngularJS and I have been able to create simple CRUD applications such as a to-do list or online store. Currently, I have always been creating the data for my web applications through regular JavaScript Arrays/Objects.. but now I want to be able to permanently edit/change this data through my own CMS user interface.

Some research has led me to use JSON and the angular $http service to request JSON data from the server.

Now, I am trying to update this JSON data Asynchronously with angularJS and I'm not sure how to do this (see below for my attempt).

Simple To-Do List Application

<body ng-controller="ToDoCtrl">

  <div class="container">
    <div class="page-header">
      <h1>
        {{todo.user}}'s To Do List &nbsp;
        <span class="label label-default" ng-hide="incompleteCount() == 0"
              ng-class="warningLevel()">
          {{ incompleteCount() }}
        </span>
      </h1>
    </div>

    <div class="panel">

      <div class="input-group">
        <input class="form-control" ng-model="actionText">
        <span class="input-group-btn">
          <button class="btn btn-success" ng-click="addItem(actionText, todo.items)">Add</button>
        </span>
      </div><!-- end input-group -->

      <table class="table table-striped">
        <thead>
          <tr>
            <th>Descriptions</th>
            <th>Done</th>
            <th>Remove</th>
          </tr>
        </thead>
        <tbody>
          <tr ng-repeat="item in todo.items | checkedItems: showComplete | orderBy: 'action'">
            <td>{{item.action}}</td>
            <td><input type="checkbox" ng-model="item.done"></td>
            <td><button ng-click="deleteItem(item, todo.items)" class="btn btn-danger">Delete</button></td>
          </tr>
        </tbody>
      </table>

      <div class="checkbox-inline">
        <label><input type="checkbox" ng-model="showComplete">Show Complete</label>
      </div>

      <div class="input-group">
        <button ng-click="save()" class="btn btn-primary">Save Changes</button>
        <p>{{msg}}</p>
      </div>

    </div><!-- end panel -->
  </div>

  <!-- Vendor JS -->
  <!-- Angular -->
  <script src="vendors/angular.min.js"></script>

  <!-- Modules -->
  <script src="app.js"></script>

</body>

app.js

var model = {
  user: "Alex"
};

angular.module('todoApp', [])

.run(function($http) {

  $http.get("todo.json").success(function(data) {
    model.items = data;
  });

})

.controller('ToDoCtrl', ['$scope', '$http', function($scope, $http) {

  $scope.todo = model;

  $scope.incompleteCount = function() {
    var count = 0;
    angular.forEach($scope.todo.items, function(item) {

      if (!item.done) { 
        count++ 
      }

    });
    return count;
  };

  $scope.warningLevel = function() {
    return $scope.incompleteCount() < 3 ? "label-success" : "label-warning";
  };

  $scope.addItem = function(actionText, sourceArray) {
    sourceArray.push(
      {
        action: actionText,
        done: false,
      }
    );

    $scope.actionText = '';
  };

  $scope.deleteItem = function(item, sourceArray) {
    for(var i = 0, j = sourceArray.length; i < j; i++) {
      if(item.action == sourceArray[i].action) {
        sourceArray.splice(i, 1);
        return;
      }
    }
  };

  $scope.save = function() {
    $http.post('C:\Users\Alex\Desktop\Development\"Web Design"\2015\todoApp\public\src\todo.json', $scope.todo.items).then(function(data) {
      $scope.msg = 'Data saved '+ JSON.stringify($scope.todo.items);
    });
  };

}])

.filter("checkedItems", function() {
  return function(items, showComplete) {
    var resultArr = [];
    angular.forEach(items, function(item) {

      if(item.done == false || showComplete == true) {
        resultArr.push(item);
      }

    });
    return resultArr;
  }
});

I used this Post for the $scope.save function, but I receive an error: "XMLHttpRequest cannot load. Cross origin requests are only supported for protocol schemes: http, data, chrome..."

  $scope.save = function() {
    $http.post('C:\Users\Alex\Desktop\Development\"Web Design"\2015\todoApp\public\src\todo.json', $scope.todo.items).then(function(data) {
      $scope.msg = 'Data saved '+ JSON.stringify($scope.todo.items);
    });
  };

Basically, I just want to update my todo.json file with the current contents of my $scope.todo.items array. I think the simplest way would be to delete the current contents of the JSON data and replace with current contents of $scope.todo.items, but I don't know much about this stuff.

Thanks for any help.

Community
  • 1
  • 1
SuperVeetz
  • 2,128
  • 3
  • 24
  • 37
  • 1
    You can't just post to your file system. You need an http server and server side application. Try [node.js](https://nodejs.org/) – Rob Aug 12 '15 at 04:53
  • Hmm, okay. I was also playing around with Node.js and I was able to start my own local Server, but I had to refresh the server everytime that I made a change to my application. Would I be able to update the `todo.json` with only Node.js? – SuperVeetz Aug 12 '15 at 04:55
  • 2
    Yes but you need to post to something like `http://localhost:3000/` or whatever you have node setup to handle your request. You can't just post to `c:\some\path` like in your example. – Rob Aug 12 '15 at 04:56
  • I will give this a try. Thanks! – SuperVeetz Aug 12 '15 at 04:58

1 Answers1

4

Let's start with some concepts first:

1.- a JSON file is just a text file, it can be a product of a database query or it can be generated dynamically by a server, but at the end of the day is just a text file.

2.- the $http service deals with request to HTTP servers, like the Apache Web Server, or NodeJS Http Server, running your software with backend technology, there's a multitude of servers and some can run in your machine as well as remotely.

3.- GET and POST are HTTP methods, that must be made to a server running your backend. The most common one, the GET method is usually used to get data from a server, like text files, or JSON files.

4.- In a file server like the one Windows provides you for local development, the GET method can bring up files from your file system (like "todo.json"). This file server is really basic, it just accepts GET requests and that's all it should accept.

5.- In your backend software, you define an Endpoint, that should be an address where your backend is ready to receive a POST request, and you also need to define what does this POST request do.

It's a long step between going from your angular file to defining an endpoint in a server, you will go across different technologies, the Angular framework is not a backend technology, it's a frontend library.

If you want to get into these concepts, a TODO List project is a great first project, sites like http://www.todobackend.com/ can show you all sort of TODO projects in a myriad of different backends and frontends.

fixmycode
  • 8,220
  • 2
  • 28
  • 43