I've recently started learning AngularJS and I was thinking about creating an application using codeigniter as the backend (as an API to insert, update and delete data to a MySQL database) and AngularJS as the frontend framework.
So my questions are: How would I accomplish this? I would I transfer the data between the two?
I wanna know a few details about it with examples because I can't find a good video tutorial where they combine the two. (found some tutorial about laravel & angular, Ruby on rails and angular but not really into those yet).
If someone knows a good video tutorial or even a blog post explaining this, please provide a link.
Found a few combo projects on GitHub but without any explanation what and how it is done, they are not really useful.
The only thing I know about this is that I have to return the data as json but I am not sure how to do that.
Thanks!
Combination of CodeIgniter and AngularJS would help you to build new range of HTML5 Applications.
Unlike JQuery, AngularJS is a front-end framework, which depends on the data from backend, all communications from the front-end happen through a Controller Methods, there are operations for get and post in Angular.
CodeIgniter will act as an API which will output an json response to the Angular controller.
I believe json_encode(data) will output the required JSON string, which upon receipt by front-end, the data presentation layer of Angular takes care of the things /or if you'd like to perform any operation over the data, Angular can do that also.
I don't hold any links for this combination, because most people have shifted towards Ruby on Rails and AngularJS combination, fearing the stop of new release of CodeIgniter
Regret for not having any satisfactory links/blog post.
If time allows me to make a proof of concept, I would be very happy to post the link.
Hope this helps.
EDIT
JSON
[
{"title": "t1"},
{"title": "t2"}
....
]
HTML
<body ng-app="app">
<div ng-controller="MsgCtrl">
<ul>
<li ng-repeat="m in msg">{{m.title}}</li>
</ul>
</div>
</body>
JS
var app = angular.module("app", []);
app.controller("MsgCtrl", function($scope, $http) {
$http.get('/index.php/ctrlname/methodname').
success(function(data, status, headers, config) {
$scope.msg = data;
}).
error(function(data, status, headers, config) {
// log error
});
});
UPDATE
For Insert, Delete, Update using CodeIgniter and AngularJS
CodeIgniter Controller
class Msg extends CI_Controller {
public function retrieveall() { .. } // Retrieves all Content from the DB
public function create(){ .. } // Inserts the given data to DB
public function retrieve($id){ .. } // Retrieves specific data from the DB
public function update($id, $title){ .. } // Updates specific data from the DB
public function delete($id){ .. } // Deletes specific data from the DB
...
}
CodeIgniter Routing
$route['m'] = "msg";
$route['m/(:any)'] = "msg/$1";
HTML
<body ng-app="app">
<div ng-controller="MsgCtrl">
<ul>
<li ng-repeat="m in msg">
{{m.title}}
Delete
Edit
</li>
</ul>
<input type="text ng-model="create.title">
<button type="submit" ng-click="formsubmit"> Submit </button>
<input type="text ng-model="editc.title">
<button type="submit" ng-click="editsubmit(editc.id)"> Submit </button>
</div>
</body>
JS
var app = angular.module("app", []);
app.controller("MsgCtrl", function($scope, $http) {
$http.get('/index.php/m/retrieveall').
success(function(data, status, headers, config) {
$scope.msg = data;
}).
error(function(data, status, headers, config) {
// log error
});
$scope.delete = function($id) {
$http.get('/index.php/m/delete/' + $id).
success(function(data, status, headers, config) {
$scope.result = data;
}
$scope.edit = function($id) {
$http.get('/index.php/m/retrieve/' + $id).
success(function(data, status, headers, config) {
$scope.editc = data;
}
$scope.editsubmit = function($id) {
$http.get('/index.php/m/update/' + $id +'/' + $scope.editc.title).
success(function(data, status, headers, config) {
$scope.result = data;
}
}
$scope.formsubmit = function($id) {
$http.post('/index.php/m/create', {data: create}).
success(function(data, status, headers, config) {
$scope.result = data;
}
}
});
I believe this would help you understand. It's a bare example
Related
I have a Controller in my Laravel project called Clientecontroller, it works perfectly. Inside it, I have a method called listar() who brings me client's information.
public function listar(Cliente $cliente) {
$clientes = DB::table('clientes')
->where('documento_id', 1)
->first();
return $clientes;
}
Sure it has some troubles but my main question is, how I call this listar() function from a view with Angular or Ajax or whatever could work.
I am working in a selling system and I have to bring the client information before selecting anything else. I want to write the ID number from the clients in my view and bring the client information from my controller without reloading. But I am still stuck in the processing reaching the listar() function.
Thank you very much.
in your routes.php file add
Route::post('/cliente', 'Clientecontroller#listar');
And now use your ajax call in order to send data to /cliente the data will be sent through to your listar method in the ClienteController.
$.ajax({
type: "POST",
url: '/cliente',
data: { id: 7 }
}).done(function( msg ) {
alert( msg );
});
This question was answered, for more details head over here
1. The classical HTML approach
Let's say you have a button on your page :
<button id="call-listar">Call !</button>
You could send an HTTP Request to your Laravel application like that :
document.querySelector('#call-listar').addEventListener('click', (e) => {
// Use the fetch() API to send an HTTP Request :
fetch('/the-url-of-listar-controller')
.then(response => response.json())
.then(json => {
// Do what you want to do with the JSON
});
});
📖 You can find a very usefull documentation about the fetch() API here : https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
2. Inside an Angular Component
This is an other story here, let's say you have this button in your HTML Template :
<button (click)="callListar()">Call !</button>
Inside your TypeScript, you could use HttpClientModule to send an HTTP Request to your Laravel App :
class MyComponent {
constructor(private http: HttpClient){}
callListar() {
this.http.get('/url-of-listar-controller')
.subscribe(response => {
// Do what you want with the response
});
}
}
WARNING : HttpClientModule needed !
You must import the HttpClientModule inside your AppModule or any other module of your Angular App where you want to use this component :
import { HttpClientModule } from '#angular/common/http';
#NgModule({
declarations: [...],
imports: [HttpClientModule]
})
I am a little confused about how to pass my database data loaded in a controller to another controller.
I load some list items from the server and on each item click I want to open the details about that item on another screen according to its id.
I read some questions about making a service or use $rootScope but $rootScope should be avoid as much as possible.
What is the best way of doing this in my case and could you show me how to do it? Should I load the data inside a service or there is an easiest way in my case?
list item using 1st controller:
<div class="item item-body list-container" id="temporada2016-list-item-container4" ng-model="item_id" ng-repeat="x in items" item="x" href="#/x/{{x.ID}}" ng-click="open_item(x)" ng-show="news_list">
<div id="temporada2016-markdown7" style="margin-top:0px;color:#666666;">
<h2 style="color:#008BBB;">{{ x.TITLE }}</h2>
</div>
</div>
1st controller
.controller('temporada2016Ctrl', ['$scope', '$http', function ($scope, $http) {
$scope.active_news_btn = true;
$scope.search_news = true;
$scope.news_list = true;
$scope.albums_list = false;
$http.get("http://localhost/select-news.php").then(function(response){
console.log(response);
console.log(JSON.stringify(response));
$scope.items = response.data;
});
$scope.open_item = function(x){
//alert("Item id: " + x.ID);
$http.post("http://localhost/select-news-by-id.php", {'item_id': x.ID}).then(function(response){
console.log(response);
console.log(JSON.stringify(response));
$scope.all = response;
$scope.title = response.data[0].TITLE;
$scope.body = response.data[0].BODY;
});
}
}])
second screen (details) using 2nd controller where I want to load the same title and news body
<ion-view title="Detalhes" id="page4" style="background-color:#FFFFFF;">
<ion-content padding="true" class="has-header">
<h3 id="detalhes-heading1" style="color:#008BBB;font-weight:600;font-style:italic;">{{title}}</h3>
<div id="detalhes-markdown3" style="color:#000000;">
<p>{{body}}</p>
</div>
<form id="detalhes-form4" class="list">
<button id="detalhes-button6" style="color:#008BBB;text-align:left;border-radius:9px 9px 9px 9px;" class="button button-calm button-clear icon ion-ios-heart-outline like_btn"></button>
<label class="item item-input" id="detalhes-textarea1">
<span class="input-label"></span><textarea placeholder=""></textarea>
</label>
</form>
<button id="detalhes-button17" style="color:#FFFFFF;" class="button button-positive">Comment</button>
</ion-content>
</ion-view>
2nd controller
.controller('detalhesCtrl', ['$scope', '$stateParams', function ($scope, $stateParams) {
}])
PHP
<?php
include_once('conn.php');
$data = json_decode(file_get_contents("php://input"));
if(property_exists($data, 'item_id')){
$item_id = $data->item_id;
$sql = $mysqli->query("SELECT * FROM news WHERE id = '".$item_id."'");
if($sql->num_rows > 0){
while($row = $sql->fetch_array(MYSQLI_BOTH)){
$registro = array(
"ID" => $row['id'],
"TITLE" => $row['title'],
"BODY" => $row['body']
);
$retorno[] = $registro;
}
}
$mysqli->close();
$retorno = json_encode($retorno);
echo $retorno;
}
?>
In your app-config
$stateProvider
.state('master', {
url: '/master',
templateUrl: 'views/master.html',
controller: 'MasterCtrl',
data: {
someThingToPassToMasterState: false
}
})
.state('details', {
url: '/details',
data : {
somethingToPassToDetailsState: false
},
templateUrl: 'views/details.html',
controller: 'DetailsCtrl'
});
And then in your MasterCtrl
$scope.onClick = function(obj) {
var dataToPass = {};
dataToPass.obj = obj;
dataToPass.somethingElse = 'blah blah';
$state.go('details', {somethingToPassToDetailsState: dataToPass});
}
// Now in the DetailsCtrl
if(!$state.params.somethingToPassToDetailsState) {
// handle this
// maybe do a $state.go('default') and then return to end execution of this controller
}
// Some code
In master.html, using ng-repeat to simulate master-details page redirection
<div ng-repeat="o in objects">
<div ng-click="redirectTo(o)">{{o.name}}</div>
</div>
The idea is to pass day directly from one state to another on state transition. You can either pay in I'd and make api call AFTER transitioning to these new state or get the response from api and then paas required data to the next state
First of all, it is highly recommended you make your http calls in a factory or a service. This will make your code more reusable and it will look something like this:
app.factory("responseFactory", function($http) {
return {
getData: function() {
//Code for making http call goes in here
$http.get("http://localhost/select-news.php").then(function(response){
return(response.data);
});
},
postData: function(x) {
$http.post("http://localhost/select-news-by-id.php", {'item_id': x.ID})
.then(function(response){
return(response.data);
});
}
};
});
You could later use this to call in your controller by injecting this factory in your controller and calling this factory something like this:
app.controller('temporada2016Ctrl', ['$scope', 'responseFactory', function ($scope, responseFactory) {
$scope.items = responseFactory.getData();
$scope.opnItem = function(x){
$scope.all = responseFactory.postData(x);
$scope.title = all.TITLE;
$scope.body = all.BODY;
}
}]);
Now, to make the data available in your second controller, you could do a few things.
Pass it through the $rootScope, which as you already said, should be avoided as much as possible to not clutter the rootScope. It can have many consequences. - NOT RECOMMENDED
Make a service call from the second controller and you will have all the data you need from the api. However, if you edit the data in the first controller and wish to make edited data available in the second controller, that will not be possible using this method. Also, making http calls is costly and it highly recommended to minimize your number of http calls in the app. - NOT RECOMMENDED
Use Angular service/factory - HIGHLY RECOMMENDED
app.factory('commonData', function() {
var data;
return{
setData: setData,
getData: getData
};
//setter
function setData(dataToBeShared) {
data = dataToBeShared;
}
//getter
function getData() {
return data;
}
});
Now you can inject this factory into your controllers and use the setter and getter methods easily. DO not forget to inject the responseFactory which we created earlier!
After injecting it into your first controller, you can call the commonData factory and use the setter method to set the data, something like this:
app.controller('temporada2016Ctrl', ['$scope', 'responseFactory', 'commonData', function ($scope, responseFactory, commonData) {
//All your controller code, including calling the factory like I earlier explained...it all goes here
commonData.setData(passTheDataThatYouWantToShare);
}]);
Now, to get the data in the other controller, all you need to do is access the factory's getter method and you get the data! That will be something like this:
app.controller('detalhesCtrl', ['$scope', '$stateParams', 'commonData', function ($scope, $stateParams, commonData) {
$scope.commonData = commonData.getData();
//Use $scope.commonData to use all the data that has come in from first controller
}]);
Now, the data that is passed from controller 1 is stored in the factory and can be retrieved in the second controller whenever you want. Suppose you would like to display them as panes, next to each other, you might want to add watchers, otherwise this method should work fine for you.
NOTE: This can be achieved without using setter and getter methods, but using them is a good practice and is very useful when an app gets bigger.
Pass data through state params using Angular UI router. It seems to me that you are using Angular UI router which comes bundled with ionic. This can also be used when you are routing. At the time of writing this answer, another answer on this thread (by SLearner) has already explained this method and if it is recommended or not is more or less your choice depending on the level of functionality you want. However, in my opinion, I would not go in with this solution. You can find some more answers on this topic on this thread: AngularJS: Pass an object into a state using ui-router
So, concluding my answer, in my opinion, it is best you go in for an angular factory. IMHO, that is the best solution. Hope your queries are answered.
Cheers!
Share data between two controller is not good practice.
We need to put the data in service which can easily be shared with any number of controllers
Service: MyService
this.dbDataSearch = function(parameters){
// Search record from database
this.resultData = data;
}
In Convtoller 1:
$scope.data = MyService.resultData;
In Convtoller 2:
$scope.data = MyService.resultData;
....
In Convtoller n:
$scope.data = MyService.resultData;
Once service variable will update all these controller variables automatically updated.
I used AngularJS to make an app for grading students. It works perfectly 90% of the time, but every now and then, it doesn't record the data. The grade given or other change made will be reflected in the DOM, but disappears when the page is refreshed.
I use an angular service to send data to a PHP file which sends it to a JSON file.
The service is set up like this:
app.factory('studentList', function($http) {
var studentService = {};
studentService.getInfo = function() {
var promise = $http.get('../data/studentList.json').then(function(response) {
return response.data;
});
return promise;
};
studentService.sendData = function(data) {
$http.post('../data/studentData.php', data)
.success(function (data, status, headers, config) {
console.log(status);
})
.error(function (data, status, headers, config) {
console.log(status);
});
};
return studentService;
});
When I give a grade or change student info, I call the sendData() function defined in the service. This sends it to the PHP file which looks like this:
<?php
$data = file_get_contents("php://input");
$file = "studentList.json";
file_put_contents($file, $data);
?>
I've used this PHP code before, and it seems to work fine in everything else I've done. Any insights?
Thank you.
I am creating a hybrid android app using wordpress json api, ionic and angularjs. I am stuck at just one thing : I am unable to list the posts in a particular category.I got the list of categories but unable to pass some parameters. Here's the code
controller.js
var app = angular.module('tsApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
views: {
home: {
templateUrl: 'index.html',
controller: 'TSController'
}
}
})
.state('category', {
url: '/category/:slug',
params: {
category: null //stores everything of catergory: slug, name etc.
},
views: {
category: {
templateUrl: 'category.html',
controller: 'CatsPostsCtrl'
}
}
});
$urlRouterProvider.otherwise('/');
})
// Home Controller
app.controller('TSController', function($scope, $http) {
$scope.categories = [];
$http.jsonp('http://localhost/khaliddev/azkarserv/api/get_category_index?callback=JSON_CALLBACK')
.success(function (data1) {
//console.log(data1);
$scope.categories = data1.categories; // response data
//console.log( $scope.categories);
}).error(function (data1) {
//console.log("BLOG failed");
});
});
// Cat Controller
app.controller('CatsPostsCtrl', function($scope, $http, $stateParams) {
console.log($stateParams);
// You can change this url to experiment with other endpoints
//http://localhost/khaliddev/azkarserv/api/?json=get_category_posts&slug=azkar-for-morning&status=publish
var postsApi = 'http://localhost/khaliddev/azkarserv/api/?json=get_category_posts&slug=' + $stateParams.slug + '&status=publish=JSON_CALLBACK';
$scope.category = $stateParams.category.name;
// This should go in a service so we can reuse it
$http.jsonp( postsApi, {cache:true} ).
success(function(data, status, headers, config) {
$scope.posts = data;
console.log( data );
}).
error(function(data, status, headers, config) {
console.log( 'Post load error.' );
});
});
The TSController display all categories but CatsPostsCtrl should display all posts in category which it doesn't. its show me in consle (Error 404), Any help is appreciated. Thanks!
index.html :
<div class="page-content">
<nav class="dashboard-menu">
<div class="row text-center" >
<div class="col-33" ng-repeat="cat in categories">
<a href="category/{{cat.slug}}" class="menu-link">
<span class="icon-folder-plus"></span>
<span>{{cat.title}}</span>
</a>
</div>
</div>
</nav>
</div>
i think you have an error here, maybe you forgot "&callback="
&status=publish=JSON_CALLBACK
Do you know that when you use JSONP your json should be wrapped ?
wikipedia JSONP
I had the same problem once, the URL was good, the preview of chrome was showing me the correct JSON but the status was 404. When i wrapped the json around angular.callbacks._0() it worked
If you have a back-end service, I would advice you to simply use "$http.get" or "$http.post"
I am experiencing the same issue as posted in a recent topic - 30702965 Accessing objects returned from a factory. In fact I have followed the advice in that response but still do not get any results in the view. As in that previous post I have created a factory:
myapp.factory("eventsService", function($http) {
var events = [];
return {
getEvents: function() {
return $http.get('data/events.php').then(function(response) {
events = response;
// console.log(response);
return events;
});
}};
});
This returns the promise which is seen in the console.log.
I coded the controller as per the advice in the response as follows:
myapp.controller('eventsController', function($scope, eventsService) {
$scope.events = [];
eventsService.getEvents().then(function(data){
$scope.events = data;
console.log(data);
});
});
Again, the console.log shows that I have got the object:
object {data: Array[2], status: 200, config: Object, statusText: "OK"}
All good so far, but I still don't get anything in the view:
<ion-content ng-controller="eventsController">
<ion-item ng-repeat="event in events">{{ event.title }} </ion-item>
</ion-content>
I'm lost as how to display the events. What am I missing?
Oh, by the way although this is a php backend going to a mysql database it is working. In fact if I don't use a service and code the http get directly into the controller it all works fine and I see the results as expected.
Please help this is driving me nuts!!