Passing Parameter to Angular - javascript

I am going to create a controller that will list distinct a selected field in a selected table in database and pass it to my API.
Currently, i am using a dirty method which is create several controller that has the field name and table name in it.
controller.js
.controller('ListDistinctCustomerCtrl', function($scope, $http) {
var xhr = $http({
method: 'post',
url: 'http://localhost/api/list-distinct.php?table=customer&field=cust_code'
});
xhr.success(function(data){
$scope.data = data.data;
});
})
.controller('ListDistinctSupplierCtrl', function($scope, $http) {
var xhr = $http({
method: 'post',
url: 'http://localhost/api/list-distinct.php?table=supplier&field=supp_code'
});
xhr.success(function(data){
$scope.data = data.data;
});
})
and this is the API file
list-distinct.php
<?php
require_once '/config/dbconfig.php';
$table = $_GET['table'];
$field = $_GET['field'];
GetData($table,$field);
function GetData($tablename,$fieldname) {
$sql = "SELECT distinct $fieldname as expr1 FROM $tablename order by expr1 asc";
try {
$db = getdb();
$stmt = $db->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode(array('data' => $data));
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
?>
I believe there is a clean and better way to do this.

You can create a service which contains methods for accessing your API. This will enable you to reduce your code duplication in your controllers, and allow for cleaner code in general.
.service('APIService', function($http){
var base = 'http://localhost/api/';
this.listDistinct = function(table, field){
return $http({
method: 'post'
, url: base + '/list-distinct.php'
, params: {
table: table
, field: field
}
});
}
});
Your controllers would inject the service and call whatever method it needs to access the api. Results will be obtained the same way by attaching a promise callback.
.controller('ListCtrl', function($scope, APIService){
APIService.listDistinct('customer', 'cust_code').then(function(data){
$scope.data = data;
})
});
For the PHP side of your code you need to use a white-list of possible table/field names to ensure safe operation. Without such a check you are vulnerable to SQL injection attacks. A simple array check would suffice.
$safeTables = ['customer', 'supplier'];
$safeFields = ['cust_code', 'supp_code'];
if (!in_array($tablename, $safeTables) || !in_array($fieldname, $safeFields)){
throw new Exception('Invalid parameter');
}

first of all, if you want to pass parameters by $http there is a cleaner method:
$http(
{
url: 'your url',
method: 'GET or POST',
params: {
// list of params
}
}
);
Now, is important for code maintenance and readability to use Service provider.
You can use Factory as service and create an API service.
Example:
angular.module( 'yourModule' ).factory( 'ServiceAPI', [ '$http', function ( $http ) {
var factory = {};
//PUBLIC METHODS
factory.method = method;
function method() {
return $http(
{
url: 'your url',
method: 'GET or POST',
params: {
// list of params
}
}
);
}
return factory;
} ] );
And now you can inject ServiceAPI on your Controller and use method function that reply with a promise of http.
angular.module( 'your module' ).controller( 'Ctrl', [ '$scope', 'ServiceAPI' ,
function ( $scope, ServiceAPI ) {
ServiceAPI.method.then( function ( data) {
$scope.data = data;
}, function(){console.err('error');} );
}
] );
AngularJS side, now is clear and readable.
I hope to be helpful for you.
Enjoy

Its time for Angular Providers
This is an example for your case:
angular.module('starter')
.factory('services', services);
function services($http) {
var services = {
customer: customer,
supplier: supplier,
};
return services;
//customer service
function customer() {
var req = {
method: 'POST',
url: 'http://localhost/api/list-distinct.php?table=customer&field=cust_code',
headers: {
'Accept' : 'application/json',
'contentType': "application/json"
}
};
return $http(req);
},
//supplier service
function supplier() {
var req = {
method: 'POST,
url: 'http://localhost/api/list-distinct.php?table=supplier&field=supp_code',
headers: {
'Accept' : 'application/json',
'contentType': "application/json"
}
};
return $http(req);
};
}
Then you call them like this from within the controller:
services.customer().then(
function(response) {
//do whatever is needed with the response
console.log(response);
},
function (error) {
console.log(error);
}
);
services.supplier().then(
function(response) {
//do whatever is needed with the response
console.log(response);
},
function (error) {
console.log(error);
}
);

Related

Problem inizialise a global variable AngularJS by calling a REST service

I want to create a global variable (httpTimeout) initialize at the start, contains a Long value returned by a synchrone call Rest Service and used it in different service
(
function () {
'use strict';
angular
.module('module')
.factory('MyService', function (
$http,
$q
){
var service = {};
var httpTimeout = function() {
return $http({
method: 'GET', '.../rest/getHttpTimeOut'
}).then(function (response) {
return response.data;
}).catch(function (err) {
return 30000;
});
};
service.myService1= function (Model) {
return $http({
method: 'POST', '..../rest/callRestService1',
data: Model, timeout : httpTimeout
}).then(function (response) {
return response.data;
});
};
service.myService2= function (Model) {
return $http({
method: 'POST', '..../rest/callRestService2',
data: Model, timeout : httpTimeout
}).then(function (response) {
return response.data;
});
};});
My rest service
#RequestMapping(value = "/getHttpTimeOut", method = RequestMethod.GET)
#ResponseBody
public long getHttpTimeOutValue() {
return timeoutValue;
}
how i can retrieve this value globally (httpTimeout) for use in other services
Thank you for your help
if your question is how to do something on application start :
look at that
After your application start you can use another service to store the value.
Also if you want to apply this comportement for all request take a look to interceptor

Convert JS Post Ajax to AngularJS Post Factory

I am trying to convert an Ajax call with WSSE authentication to an AngularJS factory.
The method is Post.
The intended use of this is to access the Adobe Analytics Rest API and return data to be converted to JSON and then visualised with d3.js.
I am not familiar with the properties that can be used in an AngularJS $http post call and so not sure what is the correct way to do the WSSE auth, dataType, callback etc.
This is the original ajax code which came from a public github repo:
(function($) {
window.MarketingCloud = {
env: {},
wsse: new Wsse(),
/** Make the api request */
/* callback should follow standard jQuery request format:
* function callback(data)
*/
makeRequest: function (username, secret, method, params, endpoint, callback)
{
var headers = MarketingCloud.wsse.generateAuth(username, secret);
var url = 'https://'+endpoint+'/admin/1.4/rest/?method='+method;
$.ajax(url, {
type:'POST',
data: params,
complete: callback,
dataType: "text",
headers: {
'X-WSSE': headers['X-WSSE']
}
});
}
};
})(jQuery);
This is the current way the code is being used with pure JS:
MarketingCloud.makeRequest(username, secret, method, params, endpoint, function(response) {
data = JSON.parse(response.responseText);
});
I want to convert this to a factory and a controller respectively.
This is what I have done for the factory so far:
app.factory('mainFactory', ['$http', function($http) {
var wsse = new Wsse ();
return function(username, secret, method, params, endpoint) {
return $http({
method: 'POST',
url: 'https://' + endpoint + '/admin/1.4/rest/?method=' + method,
data: params,
headers: {
'X-WSSE': wsse.generateAuth(username, secret)['X-WSSE']
},
dataType: 'text',
});
};
}]);
And this is what I have for the controller:
app.controller('mainController', ['$scope', 'mainFactory', function($scope, mainFactory) {
mainFactory.success(function(data) {
$scope.data = data;
});
}]);
Currently I get an error saying mainFactory.success is not a function which I assume is because the factory isn't working yet.
I have resolved this question myself. The parameters I was passing to the first function in the factory were globally defined already and therefore getting over-written.
The first function is not required anyway.
Here is the factory code:
app.factory('mainFactory', ['$http', function($http) {
var wsse = new Wsse ();
return {
getAnalytics : function (){
$http({
method: 'POST',
url: 'https://' + endpoint + '/admin/1.4/rest/?method=' + method,
data: params,
headers: {
'X-WSSE': wsse.generateAuth(username, secret)['X-WSSE']
}
})
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}
};
}]);
And here is the controller code:
app.controller('mainController', ['$scope', 'mainFactory', function($scope, mainFactory) {
$scope.title = "Inn Site";
$scope.data = mainFactory.getAnalytics();
}]);

How to change location and refresh page in angular js

I have a function :
$scope.insert = function(){
var data = {
'username' : $scope.username,
'password' : $scope.password,
'nama_lengkap' : $scope.nama_lengkap
}
$http({
method: 'POST',
url: './sys/mac.php',
data : data
}).then(function(response){
return response.data;
});
}
and the function work perfectly, but i want my page change to datalist and refresh datalist after insert() true. my function insert() run in the route "localhost/learn/#!/administrator" so i want it change to route "localhost/learn/#!/" after insert() true. i used location.href='#!/' but it not work for refresh datalist automaticaly, just change location.
If you want to update an object from a service call, you can do the following. I have added an onError function too, to help with debugging.
Tip: Research adding service calls into a Service that AngularJS framework provides. It helps for writing maintainable and structured code.
$scope.objectToUpdate;
$scope.insert = function(){
var data = {
'username' : $scope.username,
'password' : $scope.password,
'nama_lengkap' : $scope.nama_lengkap
}
$http({
method: 'POST',
url: './sys/mac.php',
data : data
}).then(function(response){
$scope.objectToUpdate = response.data.d;
}, function(e){
alert(e); //catch error
});
}
Optional Service
Below is an example of how to make use of Angular Services to make server calls
app.service('dataService', function ($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function (url, data) {
// $http() returns a $promise that we can add handlers with .then() in controller
return $http({
method: 'POST',
url: './sys/' + url + '.php',
dataType: 'json',
data: data,
headers: { 'Content-Type': 'application/json; charset=utf-8' }
});
};
});
Then call this service from your controller, or any controller that injects DataService
var data = {
'username' : $scope.username,
'password' : $scope.password,
'nama_lengkap' : $scope.nama_lengkap
}
dataService.getData('mac', data).then(function (e) {
$scope.objectToUpdate = e.data.d;
}, function (error) {
alert(error);
});

Factory "is not defined" in AngularJS

I'm a beginner in Angular world, and I can't work out why I'm still getting "not defined" error. Here is my code:
angular.module('dopasujApp').factory('getProducts', ['$http', function ($http) {
var dataFactory = {};
dataFactory.sort='ASC';
dataFactory.orderBy='PRODUCT_NAME';
dataFactory.search='a';
dataFactory.filters={};
dataFactory.filters.ATTRIBS=[46,25];
dataFactory.filters.SIZE=[165,40];
getProducts.listProducts = function() {
var request = $http({
method: "POST",
url: "http://******/backend/internalAPI.php?action=getListing&fit=1&limit=10&vendor=20",
headers: {
'Content-Type': 'application/json'
},
data: {
data: dataFactory
}
});
var products = angular.fromJson(request);
return products;
}
return false;
}]);
And here goes my controller (just for testing purposes now).
angular.module('dopasujApp')
.controller('MainCtrl', ['getProducts', '$scope','$rootScope',
function (getProducts, $scope,$rootScope) {
console.log(getProducts.listProducts())
}
]);
getProducts variable in factory is not defined. The name you used before is just informative name for angular
In your factory you are returning "false" as actual result. So angular treats your "false" as result.
It should look like that :
angular.module('dopasujApp').factory('getProducts', ['$http', function ($http) {
var dataFactory = {}, getProducts = {};
dataFactory.sort='ASC';
dataFactory.orderBy='PRODUCT_NAME';
dataFactory.search='a';
dataFactory.filters={};
dataFactory.filters.ATTRIBS=[46,25];
dataFactory.filters.SIZE=[165,40];
getProducts.listProducts = function() {
return $http({
method: "POST",
url: "http://******/backend/internalAPI.php?action=getListing&fit=1&limit=10&vendor=20",
headers: {
'Content-Type': 'application/json'
},
data: {
data: dataFactory
}
});
}
return getProducts;
}]);
Controller
angular.module('dopasujApp').controller('MainCtrl', ['getProducts', '$scope','$rootScope',
function (getProducts, $scope,$rootScope) {
getProducts.listProducts().then(function(res) {
console.log(res.data);
});
}
]);
EDIT:
Also note, that $http returns promise, but not actual query result, updated my example accordingly
try like this
var yourapp = angular.module('dopasujApp', []); //your defining your app first
yourapp.factory('getProducts', function ($http)
{
return {
//write your factory methods
};
});
you controller should be like below
yourapp.controller('MainCtrl', function PostController($scope, getProducts, $compile)
{
//here your controller methods
});

How to use HTTP.GET in AngularJS correctly? In specific, for an external API call?

I have the following code in the controller.js,
var myApp = angular.module('myApp',[]);
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
$http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
return data
}).error(function(){
alert("error");
});
}
});
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = dataService.getData();
});
But, I think I m probably making a mistake with CORS related issue. Can you please point me to the correct way to make this call? Thanks much!
First, your success() handler just returns the data, but that's not returned to the caller of getData() since it's already in a callback. $http is an asynchronous call that returns a $promise, so you have to register a callback for when the data is available.
I'd recommend looking up Promises and the $q library in AngularJS since they're the best way to pass around asynchronous calls between services.
For simplicity, here's your same code re-written with a function callback provided by the calling controller:
var myApp = angular.module('myApp',[]);
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(callbackFunc) {
$http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
// With the data succesfully returned, call our callback
callbackFunc(data);
}).error(function(){
alert("error");
});
}
});
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData(function(dataResponse) {
$scope.data = dataResponse;
});
});
Now, $http actually already returns a $promise, so this can be re-written:
var myApp = angular.module('myApp',[]);
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
// $http() returns a $promise that we can add handlers with .then()
return $http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
});
}
});
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData().then(function(dataResponse) {
$scope.data = dataResponse;
});
});
Finally, there's better ways to configure the $http service to handle the headers for you using config() to setup the $httpProvider. Checkout the $http documentation for examples.
I suggest you use Promise
myApp.service('dataService', function($http,$q) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
deferred = $q.defer();
$http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
// With the data succesfully returned, we can resolve promise and we can access it in controller
deferred.resolve();
}).error(function(){
alert("error");
//let the function caller know the error
deferred.reject(error);
});
return deferred.promise;
}
});
so In your controller you can use the method
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData().then(function(response) {
$scope.data = response;
});
});
promises are powerful feature of angularjs and it is convenient special if you want to avoid nesting callbacks.
No need to promise with $http, i use it just with two returns :
myApp.service('dataService', function($http) {
this.getData = function() {
return $http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
return data;
}).error(function(){
alert("error");
return null ;
});
}
});
In controller
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData().then(function(response) {
$scope.data = response;
});
});
Try this
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
Just setting useXDomain = true is not enough. AJAX request are also send with the X-Requested-With header, which indicate them as being AJAX. Removing the header is necessary, so the server is not rejecting the incoming request.
So you need to use what we call promise. Read how angular handles it here, https://docs.angularjs.org/api/ng/service/$q. Turns our $http support promises inherently so in your case we'll do something like this,
(function() {
"use strict";
var serviceCallJson = function($http) {
this.getCustomers = function() {
// http method anyways returns promise so you can catch it in calling function
return $http({
method : 'get',
url : '../viewersData/userPwdPair.json'
});
}
}
var validateIn = function (serviceCallJson, $q) {
this.called = function(username, password) {
var deferred = $q.defer();
serviceCallJson.getCustomers().then(
function( returnedData ) {
console.log(returnedData); // you should get output here this is a success handler
var i = 0;
angular.forEach(returnedData, function(value, key){
while (i < 10) {
if(value[i].username == username) {
if(value[i].password == password) {
alert("Logged In");
}
}
i = i + 1;
}
});
},
function() {
// this is error handler
}
);
return deferred.promise;
}
}
angular.module('assignment1App')
.service ('serviceCallJson', serviceCallJson)
angular.module('assignment1App')
.service ('validateIn', ['serviceCallJson', validateIn])
}())
Using Google Finance as an example to retrieve the ticker's last close price and the updated date & time. You may visit YouTiming.com for the run-time execution.
The service:
MyApp.service('getData',
[
'$http',
function($http) {
this.getQuote = function(ticker) {
var _url = 'https://www.google.com/finance/info?q=' + ticker;
return $http.get(_url); //Simply return the promise to the caller
};
}
]
);
The controller:
MyApp.controller('StockREST',
[
'$scope',
'getData', //<-- the service above
function($scope, getData) {
var getQuote = function(symbol) {
getData.getQuote(symbol)
.success(function(response, status, headers, config) {
var _data = response.substring(4, response.length);
var _json = JSON.parse(_data);
$scope.stockQuoteData = _json[0];
// ticker: $scope.stockQuoteData.t
// last price: $scope.stockQuoteData.l
// last updated time: $scope.stockQuoteData.ltt, such as "7:59PM EDT"
// last updated date & time: $scope.stockQuoteData.lt, such as "Sep 29, 7:59PM EDT"
})
.error(function(response, status, headers, config) {
console.log('### Error: in retrieving Google Finance stock quote, ticker = ' + symbol);
});
};
getQuote($scope.ticker.tick.name); //Initialize
$scope.getQuote = getQuote; //as defined above
}
]
);
The HTML:
<span>{{stockQuoteData.l}}, {{stockQuoteData.lt}}</span>
At the top of YouTiming.com home page, I have placed the notes for how to disable the CORS policy on Chrome and Safari.
When calling a promise defined in a service or in a factory make sure to use service as I could not get response from a promise defined in a factory. This is how I call a promise defined in a service.
myApp.service('serverOperations', function($http) {
this.get_data = function(user) {
return $http.post('http://localhost/serverOperations.php?action=get_data', user);
};
})
myApp.controller('loginCtrl', function($http, $q, serverOperations, user) {
serverOperations.get_data(user)
.then( function(response) {
console.log(response.data);
}
);
})

Categories

Resources