0

Ok, so I'm stuck again. I'm doing an todo-list application, using Laravel and Angular. I can fetch data from the database via the Laravel- and Angular controllers but when I try do write data, I can't get it working.

So I have a form, whing uses ng-submit to post the data. When I - in the Angular controller - log the data to the console, the data from the form is correct. But when I try to pass it on to the Laravel Controller, I get stuck.

I can't find out whats wrong and browing the web for answers hasn't helped me.

Laravel routes:

<?php
Route::get('/', function () {
    return view('index');
});
Route::get('/notes', 'NoteController@index');
Route::delete('/notes', 'NoteController@destroy');
Route::post('/notes', 'NoteController@store');
//Route::post('/notes', 'NoteController@update');
Route::get('/projects', 'ProjectController@index');
Route::get('/users', 'UserController@index');
Route::group(['middleware' => ['web']], function () {
    //
});
?>

Laravel controllers:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Note;
use App\User;
use App\Project;
use Input;
use Response;
use Redirect;
class NoteController extends Controller
{
    public function index()
    {
        try {
            $statusCode = 200;
            $notes = Note::where('removed', 0)->get()->toArray();
            $response = [];
            foreach ($notes as $note) {
                $user = User::find($note['user_id']);
                $project = Project::find($note['project_id']);

                $this_row = array(
                    'id' => $note['id'],
                    'user' => $user['uname'],
                    'project' => $project['pname'],
                    'content' => $note['content'],
                    'completed' => $note['completed'],
                    'removed' => $note['removed'],
                    'created' => $note['time_created'],
                    'deadline' => $note['time_deadline']
                );
                $response[] = $this_row;
            }
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }

    public function store()
    {
        $note = Input::json()->get()->toArray();
        var_dump($note);
        /*
        $note->user_id = $note['user'];
        $note->project_id = $note['project'];
        $note->content = $note['content'];
        $note->time_deadline = $note['deadline'];
        $note->save();*/
    }
}

class ProjectController extends Controller
{
    public function index()
    {
        try {
            $statusCode = 200;
            $projects = Project::orderBy('pname', 'asc')->get()->toArray();
            $response = [];
            foreach ($projects as $project) {
                $this_row = array(
                    'id' => $project['id'],
                    'name' => $project['pname'],
                );
                $response[] = $this_row;
            }
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }
}

class UserController extends Controller
{
    public function index()
    {
        try {
            $statusCode = 200;
            $users = User::orderBy('uname', 'asc')->get()->toArray();
            $response = [];
            foreach ($users as $user) {
                $this_row = array(
                    'id' => $user['id'],
                    'name' => $user['uname'],
                );
                $response[] = $this_row;
            }
        } catch (Exception $e) {
            $statusCode = 400;
        } finally {
            return Response::json($response, $statusCode);
        }
    }
}

Angular controller:

angular.module('todoApp', []).controller('MainController', function($scope, $http) {
    var thisApp = this;

    $http({method : 'GET', url : 'http://localhost:8000/notes'})
        .then (function(response) {
            thisApp.todos = response.data;
        }, function() {
            alert("Error getting todo notes");
        });

    $http({method : 'GET',url : 'http://localhost:8000/users'})
        .then(function(response) {
            thisApp.users = response.data;
        }, function() {
            alert("Error getting users");
        });
    $http({method : 'GET', url : 'http://localhost:8000/projects'})
        .then(function(response) {
            thisApp.projects = response.data;
        }, function() {
            alert("Error getting projects");
        });
    thisApp.addTodo = function(note) {
        console.log($scope.note);
        $http({
            method : 'POST', 
            url : 'http://localhost:8000/notes',
            data : $.param($scope.note),
            headers : {'Content-Type': 'application/x-www-form-urlencoded'}
        });
    };
});

HTML:

<!doctype html>
<html ng-app="todoApp">
    <head>
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        <script src="/js/MainController.js"></script>
    </head>
    <body ng-controller="MainController as myControl">
        <h2>Todo</h2>
        <div>
            <table>
                <tr>
                    <th>Note:</th>
                    <th>Author:</th>
                    <th>Project:</th>
                    <th>Created:</th>
                    <th>Deadline:</th>
                </tr>
                <tr ng-repeat="todo in myControl.todos">
                    <td> {{ todo.content }} </td>
                    <td> {{ todo.user }} </td>
                    <td> {{ todo.project }} </td>
                    <td> {{ todo.created }} </td>
                    <td> {{ todo.deadline }} </td>
                    <td><button>Update</button></td>
                    <td><button>Delete</button></td>
                </tr>
            </table>
        </div>
        <h2>Add new:</h2>
        <div>
            <form ng-submit="myControl.addTodo()">
                User:<br/>
                <select ng-model="note.user">
                    <option ng-repeat="user in myControl.users" value="{{ user.id }}">{{ user.name }}</option>
                </select><br/>
                Project:<br/>
                <select ng-model="note.project">
                    <option ng-repeat="project in myControl.projects" value="{{ project.id }}">{{ project.name }}</option>
                </select><br/>
                Note:<br/>
                <textarea rows="5" cols="30"  ng-model="note.content"></textarea><br/>
                Deadline (format YYYY-MM-DD HH:MM):<br/>
                <input type="text" ng-model="note.deadline" /><br/>
                <input type="submit" value="Add" />
            </form>
        </div>
    </body>
</html>

The result can be seen in this image: https://i.stack.imgur.com/CMTNA.jpg

I have no idea what I'm doing wrong. I guess my problem is in the Angular controller in the addTodo function, but I really don't know. Any suggestions?

I also wonder if anyone knows if I have to do anything else than change method : 'POST' to method : 'PUT' if I want to use the PUT method for creating new notes?

Gupta
  • 8,882
  • 4
  • 49
  • 59
BluePrint
  • 1,926
  • 4
  • 28
  • 49
  • Are you able to get `console.log` ? Are you sure your page is not refreshing once you click submit button ? – Rayon Jan 05 '16 at 11:45
  • @RayonDabre `console.log($scope.note);` in the Angular controller gives the following: `Object {user: "1", project: "2", deadline: "2015-12-31 00:05:00", content: "sadasd"}` which is correct, I think. I don't know if I refresh, but I don't think so. – BluePrint Jan 05 '16 at 11:53
  • `500 Internal Server` as it says your Server Side coding has error. Pls have a view on it and fix it – Sulthan Allaudeen Jan 05 '16 at 11:55
  • 500, it might [csrf](http://stackoverflow.com/questions/18336699/how-to-send-csrf-token-inside-angularjs-form-using-laravel-api) or something on server. – Bagus Tesa Jan 05 '16 at 12:57
  • Open the Network tab in Chrome developer tools & view Response on your request to get the exact error message. You can also check the logs in storage/logs folder to get the error message. – Vikas Jan 05 '16 at 18:04

2 Answers2

0

I feel like it has something to do with this:

$note = Input::json()->get()->toArray();
var_dump($note);

In angular you are sending form encoded data not json. And I believe Laravel automatically decodes received json anyway, so this should work:

$note = Input::all();
var_dump($note);
Rai
  • 656
  • 1
  • 6
  • 14
0

If it is the CSRF token then inject the CSRF TOKEN to your view

   angular.module("todoApp").constant("CSRF_TOKEN", '{!! csrf_token() !!}');

and to your addTodo function in the headers pass the token....

 thisApp.addTodo = function(note) {
    console.log($scope.note);
    $http({
        method : 'POST', 
        url : 'http://localhost:8000/notes',
        data : $.param($scope.note),
        headers : {'Content-Type': 'application/x-www-form-urlencoded',
                               'x-csrf-token': CSRF_TOKEN}
    });
Leo
  • 1,521
  • 12
  • 18