This article mainly introduces how to use AngularJS and PHP's Laravel to implement single-page comments. The example in this article is a model of frontend JavaScript and backend PHP joint programming. If you need it, you can refer to the complete code: https://github.com/scotch-io/laravel-angular-comment-app
At present, Laravel and Angular have become very famous tools in the world of Web development. Laravel is famous for introducing great content to the PHP community. Angular is famous for its amazing front-end tools and simplicity. Combining these two frameworks seems to be a logical next step.
In our use environment, we will use Laravel as the backend RESTful API and Angular as the front end to create a simple single-page comment application.
The following is a simple example of how to start using these two technologies, so you don't have to worry about additional database features or how to handle comments.
What will we create
This will be a simple single-page comment application:
- RESTful Laravel API processes the acquisition, creation, and deletion of comments;
- Angular frontend displays the created forms and comments;
- You can create a new comment and add it to our W/O page to refresh the list;
- You can delete a comment and remove it from the W/O page refresh list.
In general, these are very simple concepts. We focus on the intricate relationships between Laravel and Angular.
Laravel backend
Set Laravel
Continue to set up your Laravel. We will do some basic work to add, delete, modify, and query comments on Our backend:
- Create a database for Migration
- Implant sample comments into the database
- Create a route table for our API
- Create a "get all" route table for Angular Routing
- Create a Resource Controller for comments
Prepare database migration
We need a simple structure that stores comments, including content and author. Let's create a Laravel migration to create a comment.
Run the artisan command to create a comment migration, so that you can create a comment table in our database:
php artisan migrate:make create_comments_table --create=comments
We will use the Laravel mode builder to create the required "content" and "author" fields. Laravel will also create the id and timestamps columns so that we can know when to add this comment. The code for the comment table is as follows:
// app/database/migrations/####&##_######_create_comments_table.php
...
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function(Blueprint $table)
{
$table->increments('id');
$table->string('text');
$table->string('author');
$table->timestamps();
});
}
...
Make sure that you have adjusted the database settings with the correct credential in the "app/config/database. php" file. Now we run the migration to create the table with the required columns:
php artisan migrate
Comment Model
We will use the Laravel Eloquent model to interact with the database. This is easy to implement. Let's create a model: "app/models/Comment. php ":
<?php
// app/models/Comment.php
class Comment extends Eloquent {
// let eloquent know that these attributes will be available for mass assignment
protected $fillable = array('author', 'text');
}
Now that we have tables and models, we can use Laravel Seeding to add a sample data to the table.
Seeding Database
We need some comments to test several things. Let's create a seed file and insert three sample comments to the database.
Create an app/database/seeds/CommentTableSeeder. php file and add the following code:
<?php
// app/database/seeds/CommentTableSeeder.php
class CommentTableSeeder extends Seeder
{
public function run()
{
DB::table('comments')->delete();
Comment::create(array(
'author' => 'Chris Sevilleja',
'text' => 'Look I am a test comment.'
));
Comment::create(array(
'author' => 'Nick Cerminara',
'text' => 'This is going to be super crazy.'
));
Comment::create(array(
'author' => 'Holly Lloyd',
'text' => 'I am a master of Laravel and Angular.'
));
}
}
To call this seeding machine file, modify "app/database/seeds/DatabaseSeeder. php" and add the following code:
// app/database/seeds/DatabaseSeeder.php
...
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Eloquent::unguard();
$this->call('CommentTableSeeder');
$this->command->info('Comment table seeded.');
}
...
Now we use the artisan command to run our seeding machine.
php artisan db:seed
Now we have a database containing a comment table, a Eloquent model, and some database samples. A day's work is not bad... But we are far from over.
Comment on Resource Controller (app/controllers/CommentController. php)
We will use the Laravel Resource Controller to process comments. Because Angular is used to display a resource and create and update forms, we will use the artisan command to create a resource controller without creating and editing functions.
Let's use artisan to create a resource controller.
php artisan controller:make CommentController --only=index,store,destroy
For the example application, we only use these three functions in the Resource Controller. To expand, you need to include all functions such as update and display to implement a more mature application.
If you have created a controller, you do not need to create or edit a function. Because Angular, rather than Laravel, processes the display form. Laravel is only responsible for returning data to the front end. To simplify things, we also propose update functions from the instance application. We will process the creation, display, and deletion of comments.
To return data, we want to return data in JSON format. Let's look at the newly created controller and add the corresponding function.
<?php
// app/controllers/CommentController.php
class CommentController extends \BaseController {
/**
* Send back all comments as JSON
*
* @return Response
*/
public function index()
{
return Response::json(Comment::get());
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
Comment::create(array(
'author' => Input::get('author'),
'text' => Input::get('text')
));
return Response::json(array('success' => true));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
Comment::destroy($id);
return Response::json(array('success' => true));
}
}
You can see how easy it is to use Laravel and Eloquent to process addition, deletion, modification, and query. Processing the functions we need is incredibly simple.
As the controller is ready, the last thing we need to do at the backend is routing.
Our route table (app/routes. php)
As the database is ready, let's process the route table of the Laravel application. Since it has its own route, we will use the route table to send data to the front-end. We also need to provide a route table for backend APIs to allow users to access our comment data.
Let's create an Angular pointing to a route table. We need a homepage route table and a "get all" route table sent to Angular. This ensures that users can access our website in any way and they will be routed to the Angular front-end.
We will use... (drum)... api as the prefix of the API route table. In this way, if someone wants to get all the comments, they will use URL: http://example.com/api/comments. This is just a meaningful advance and a good strategy for creating basic APIs.
<?php
// app/routes.php
// =============================================
// HOME PAGE ===================================
// =============================================
Route::get('/', function()
{
// we dont need to use Laravel Blade
// we will return a PHP file that will hold all of our Angular content
// see the "Where to Place Angular Files" below to see ideas on how to structure your app
return View::make('index'); // will return app/views/index.php
});
// =============================================
// API ROUTES ==================================
// =============================================
Route::group(array('prefix' => 'api'), function() {
// since we will be using this just for CRUD, we won't need create and edit
// Angular will handle both of those forms
// this ensures that a user can't access api/create or api/edit when there's nothing there
Route::resource('comments', 'CommentController',
array('only' => array('index', 'store', 'destroy')));
});
// =============================================
// CATCH ALL ROUTE =============================
// =============================================
// all routes that are not home or api will be redirected to the frontend
// this allows angular to route them
App::missing(function($exception)
{
return View::make('index');
});
We now have a route table to handle three main tasks Laravel has to do.
Process the "get all" route table: In Laravel, You can implement this in several ways. Generally, it is not ideal to use the above Code and obtain "get all" for the entire application. You can use the Laravel controller's loss method to obtain the route table.
Test all route tables so that all the required route tables are available. We will use artisan to view all route tables:
php artisan routes
This command shows all route tables and a top-down application view.
We can see the HTTP verb and get all comments, and get, create, and destroy the route table of a comment. At the top of the API route table, you can see how a user routes to Angular through the homepage route table.
Background complete
Finally! The background of Laravel API is complete. We have done a lot, but there is still a lot of work to do. We have created and planted databases, created models and controllers, and created route tables. Let's continue working on the Angular front-end.
Where to place Angular files
I have seen this question many times. Where should I put Angular files and how can I make Laravel and Angular work together.
For Angular to process the front-end, Laravel needs to direct the user to the index. php file. We can place it in several different places. By default, when you use:
// app/routes.php
Route::get('/', function() {
return View::make('index');
});
This will return app/views/index. php. Laravel will be searched in the app/views folder by default.
Some people want to completely separate Angular files from Laravel files. They want to put their entire application in the public folder. This is simple: you only need to set the default View location to the public folder. You can modify the app/config/view. php file to complete the settings.
// app/config/view.php
...
// make laravel look in public/views for view files
'paths' => array(__DIR__.'/../../public/views'),
...
Now, return View: make ('index') will find the public/views/index. php file. You can configure how you want to organize your app. Some people think that it is more advantageous to put the entire Angular application in the public folder, which can easily process routes and, if necessary in the future, the RESTful API at the backend can be completely separated from the Angular at the front end.
To enable Angular routing, some of your files need to be placed in the public folder, but this is beyond the scope of this article.
Let's assume that all things use the default value, and our main view file is in our app/views folder, and then we continue.
If Laravel conflicts with Angular routes, many problems may occur. Laravel will take control of your applications as the main route. Angular routes only occur when Laravel routes our users to the Angular main route (index. php. This is why we use Laravel to control all the routes. Laravel will process API routes and send requests that do not know how to route to Angular. Then, you can set all routes for your Angular application to view different views.
Angular
Prepare our application
Everything in our Angular program must be processed in the public folder. This helps us to distinguish it from the files in the backend app folder.
Let's take a look at the organizational structure in our public folder. We have created a modular Angular program because it is the best practice. Now, we can easily test and process each part of our program.
- -Public/
- ----- Js/
- ---------- Controllers // where we will put our angular controllers
- --------------- MainCtrl. js
- ---------- Services // angular services
- --------------- CommentService. js
- ---------- App. js
Angular Service public/js/services/commentService. js
Our Angular service is a major location for calling Laravel APIs through HTTP. It is very concise and easy to understand. We use Angular $ http service.
// public/js/services/commentService.js
angular.module('commentService', [])
.factory('Comment', function($http) {
return {
// get all the comments
get : function() {
return $http.get('/api/comments');
},
// save a comment (pass in comment data)
save : function(commentData) {
return $http({
method: 'POST',
url: '/api/comments',
headers: { 'Content-Type' : 'application/x-www-form-urlencoded' },
data: $.param(commentData)
});
},
// destroy a comment
destroy : function(id) {
return $http.delete('/api/comments/' + id);
}
}
});
This is our Angular service, which contains three different functions. These are the only functions we need, because they will correspond to the routing api in Laravel.
Our service will return a promise object. These will be used to process our controllers. The naming conventions here are also consistent with our Laravel controller.
After finishing our Angular service, let's start with our controller and use it.
Angular controller public/js/controllers/mainCtrl. js
This controller implements most of the functions of our application. Here we create a function to process the submission form and delete the comment.
// public / js / controllers / mainCtrl.js
angular.module ('mainCtrl', [])
// in the controller such as Comment service
.controller ('mainController', function ($ scope, $ http, Comment) {
// object holding all form data for the new comment
$ scope.commentData = ();
// call a variable that displays the loading icon
$ scope.loading = true;
// Get all comments first, then bind them to the $ scope.comments object // Use the function defined in the service
// GET ALL COMMENTS ================================================== =======
Comment.get ()
.success (function (data) {
$ scope.comments = data;
$ scope.loading = false;
});
// function that handles submitting the form
// SAVE A COMMENT ================================================== ==========
$ scope.submitComment = function () {
$ scope.loading = true;
// Save the comment. Passing comments between forms
// use functions created in the service
Comment.save ($ scope.commentData)
.success (function (data) {
// If successful, we need to refresh the comment list
Comment.get ()
.success (function (getData) {
$ scope.comments = getData;
$ scope.loading = false;
});
})
.error (function (data) {
console.log (data);
});
};
// function to delete comments
// DELETE A COMMENT ================================================== =======
$ scope.deleteComment = function (id) {
$ scope.loading = true;
// use functions created in the service
Comment.destroy (id)
.success (function (data) {
// If successful, we need to refresh the comment list
Comment.get ()
.success (function (getData) {
$ scope.comments = getData;
$ scope.loading = false;
});
});
};
});
As you can see in the controller, We have injected the Comment service and used it to implement the main functions: Get, save, and delete. Use such a service to avoid using $ http get or put to pollute our controller.
Connect to our application public/js/app. js
In Angular, we have created services and controllers. Now let's connect them together, so that we can use ng-app and ng-controller to apply it to our application.
This is the code for creating an Angular application. We will inject services and controllers. This is a best practice that makes our applications modular and different parts are measurable and scalable.
// public/js/app.jsvar commentApp = angular.module('commentApp', ['mainCtrl', 'commentService']);
In this way, there is not much work. Now we have implemented our point of view. We can see how Angular works together.
Our main view app/views/index. php
So far, after all preparations, we still cannot see anything from the browser. Because Laravel controls our master route, we need to define our View file and return the return View: make ('index'); For all route requests ');.
Let's create a view first. We will use all Angular content we have created. The main part we have created using Angular will be the main component we will use in index. php:
- Ng-app and ng-controller: Apply them by attaching them to the body tag
- Ng-repeat: displays comments to the template through Loops
- SubmitComment (): Use ng-submit to append this function to the form.
- Loading Icons: we will create a variable called loading. If it is set to true, a loading icon is displayed and comments are hidden.
- DeleteComment (): We will append this function to a delete link so that we can delete the comment.
Now let's write the actual code that implements our point of view. We will comment out the main important parts so that we can see how everything works normally.
Laravel and Angular Comment System