Im writing an application which connects to a 3rd party api.
The api uses a auth token system so i have an async node js function which first requests the token and then uses that token to retrieve some data.
The problem is that when the data changes the angualr $scope wont update so the page will show the same data even if an error is thrown in the node js api call.
A little run through the code.
get-salesLead-data.js Has a Async waterfall function which firsts calls the 3rd party rest api using http PUT and returns an auth token. This token is then passed into the second function of the Async water which is then used to make a http GET request to get the sales lead data.
Here is the Node Async api call.
**get-saleLead-data.js**
// app/get-SalesLead-data.js
// modules =================================================
var http = require('http');
var express = require('express')
var async = require('async');
module.exports = function(app) {
Using async to preform async api calls and passing data between them
async.waterfall([
// First function is requesting the auth token
requestToken = function(callback) {
var options = {
"host": "********",
"path": '************'
"method": "PUT",
"headers": {
"Content-Type": "application/json",
}
};
var login = JSON.stringify({
"username": "********",
"password": "********",
"client_ip_address": "********"
});
var req = http.request(options, function(res) {
res.on('data', function(body) {
var body = JSON.parse(body);
var token = body.token;
console.log(token);
callback(null, token);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(login);
req.end();
},
// Second function is using the auth token receieved from the first function to get sales lead dat
getData = function(arg1, callback) {
// Geting the sales id from the url and using it in the api request.
app.get('/', function(req, res) {
app.set('salesLeadId', req.query.id);
var token = arg1;
var auth = 'Basic ' + new Buffer('********' + ':' + token).toString('base64');
var path = '****************' + app.get('salesLeadId');
var options = {
"host": "********",
"path": path,
"method": "GET",
"headers": {
"Content-Type": "application/json",
"Authorization": auth
}
};
var data = '';
// Assinging response data to to data
var req = http.request(options, function(res) {
res.on('data', function(chunk) {
data += chunk;
});
// Creating sales lead api so the front end can make requests
res.on('end', function(res) {
var body = JSON.parse(data);
console.log(body);
app.get('/api/salesLead', function(req, res) {
return res.json(body);
$scope.$apply();
});
})
});
req.on('error', function() {
alert('error');
});
res.sendFile('index.html', {
root: '../vpbx/public/views'
});
req.end();
});
}
], function(err, result) {
});
};
Below is the service which accesses /api/salesLead
Creating a function which calls the backend usinga http GET request. This then returns the sales lead data.
**salesLeadService.js**
angular.module('SalesLeadService', []).service('SalesLeadService', function($http, $location, $rootScope) {
var urlBase = '/api/salesLead'
this.getSalesLead = function (data) {
return $http.get(urlBase, data)
};
});
below is the offer controller. This calls the service above and assigns the data to the $scope.salesLead.
**offer.js**
// Form controller
// =============================================================================
angular.module('offerController', []).controller('offerController', function($scope, $http, SalesLeadService, $timeout) {
// GETTING THE DATE-TIME STAMP
$scope.getDate = new Date();
$scope.date = Date();
// CALLING THE FUNCTION FROM THE SALES LEAD SERVICE
SalesLeadService.getSalesLead()
.then(function(response) {
$scope.salesLead = response.data;
$scope.$applyAsync();
});
});
Just a note that i have tried using $scope.$apply but havnt had any luck.
Any help is appreciated
Thanks
Try with object like this way
$scope.object = {salesLead : ''};
$scope.object.salesLead = response.data;
HTML
use {{object.salesLead}}
I think it will work for you
offer.js
angular.module('offerController', []).controller('offerController', function($scope, $http, SalesLeadService, $timeout) {
// GETTING THE DATE-TIME STAMP
$scope.getDate = new Date();
$scope.date = Date();
// CALLING THE FUNCTION FROM THE SALES LEAD SERVICE
$scope.object = {salesLead:''};
SalesLeadService.getSalesLead()
.then(function(response) {
$scope.object.salesLead = response.data;
$scope.$applyAsync();
});
});
I found the issue wasnt to do with the front end but my backend.
The issue was that i had a nested route.
To fix the issue i completely rewrote my routes.
Related
I am trying to make GET request with node request module. I am making request to the coursera api. As the api is using CORS. Therefore I have to make server side requests.
But the thing is how to use this data in index.html to dynamically fill data.
As here I am getting the whole data to the file. Is there any way to give this data to the Angular controller.
In brief, I want to use data from coursera api inside my angular app. I have used client side so know less about server side.
var request = require("request");
var fs = require("fs");
request("https://api.coursera.org/api/courses.v1").pipe(fs.createWriteStream("data.json"));
There are two ways you can get the data into index.html:
1) Use Jade (Pug) Render:
var COURSERA_DATA = null;
router.get('/', function (req, res) {
if (!COURSERA_DATA) {
request("https://api.coursera.org/api/courses.v1",function(err,res,body) {
COURSERA_DATA = body; /* verify first */
res.render('index', {data: COURSERA_DATA});
});
} else {
res.render('index', {data: COURSERA_DATA});
}
});
and then in index.html:
script(text/javascript).
var theDATA = !{JSON.stringify(data)}; // inserted by jade
and finally in angular1
app.controller('AnyController',function() {
var vm = this;
vm.data = theDATA;
});
2) Client request to URL which is proxied to coursera's API
router.get('/coursera', function (req, res) {
request("https://api.coursera.org/api/courses.v1").pipe(res);
}
Aaron
Why the problem to consume data right in Angular? Something like:
app.controller('controller', function($scope, $http) {
$scope.getCursera = function() {
$http({
url: "https://api.coursera.org/api/courses.v1",
method: "GET",
contentType: "application/json"
}).success(function(data) {
$scope.jsonResponse = data;
}).error(function(err) {
console.log(err);
});
};
});
If Coursera allow Cross Domain this it's works. The JSON response will be setted at the scope, such that you be able to show in view or do anything.
You can try to implement a simple api to send the response back to your controller like this..
In the server side .. (Demo)
var request = require('request');
router.get('/coursera', function (req, res,next) {
request.get(
'https://api.coursera.org/api/courses.v1',
{ json: { key: 'value' } },
function (error, response, body) {
if (!error && response.statusCode == 200) {
res.send(body); //response from coursera
// if you are using this as middleware write next()
}else {
res.send(new Error("Error while connecting to coursera"));
// if you are using this as middleware write next(err)
}
);
}
And in the angular controller ..
app.controller('controller', function($scope, $http) {
$scope.getCoursera = function() {
$http({
url: "baseURL/coursera",
method: "GET",
}).success(function(data) {
$scope.data = data;
}).error(function(err) {
console.log(err);
});
};
});
here is my javascript code
$scope.addUser = function () {
debugger;
url = baseURL + "AddUser";
$scope.objUser = [];
$scope.objUser.push( {
"ID": '0',
"UserName": $scope.txtUserName,
"Password": $scope.txtPassword,
"Role":"Non-Admin"
});
$http.post(url,$scope.objUser[0])
.success(function (data) {
debugger;
alert("S");
window.location = "../View/Login.html";
}).error(function () {
debugger;
alert("e");
});
}
here is my server method code
[HttpPost]
public int AddUser(UserModel user)
{
//_entity.Configuration.ProxyCreationEnabled = false;
tblUser objUser = new tblUser();
objUser.UserName = user.UserName;
objUser.Password = user.Password;
objUser.Role = user.Role;
_entity.tblUsers.Add(objUser);
_entity.SaveChanges();
return objUser.ID;
}
You can use promises to get the response. this can be inside into a service and call it whenever you want to use it.
this.addUser = function (obj) {
var datosRecu = null;
var deferred = $q.defer();
var uri = baseUrl + 'addUser';
$http({
url: uri,
method: 'post',
data: angular.toJson(obj)
}).then(function successCallback(response) {
datosRecu = response;
deferred.resolve(datosRecu);
}, function errorCallback(response) {
datosRecu = response;
deferred.resolve(datosRecu);
});
return deferred.promise;
};
Also .error and .success are deprecated.
PD: the parameter data: inside the $http correspond to the body. if you want to send parameters you should use params:{}
EDIT:
Here i leave you a link how promises work. Angular promises
Basically this helps to process data asynchronously
the example above can be used inside a service like this
myApp.service('myService', function($q, $http){
// here your services....
});
the service can be injected inside to any controller to provide the data that what you want, inside of your functions
myApp.controller('myController', function($scope, myService){
$scope.list = function(){
$promise = myService.getAll(); // this will be the name of your function inside your servive
$promise.then(function(data){
console.log(data); //here you can se your promise with data like status and messages from the server.
});
};
});
Hope it helps.
I am new to MEAN applications.Here I have a REST based sample application using node-restful library in which I can perform operations(get,save,delete) except 'put'. However 'put' operation works well on rest clients (advanced REST, postman) but not on angular client.
mongoose Model
var restful = require('node-restful');
var mongoose = restful.mongoose;
// Schema
var productSchema = new mongoose.Schema({
name: String,
college: String,
age: Number
});
// Return model
module.exports = restful.model('Products', productSchema);
Node-express code
var express = require('express');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var cors =require('cors');
// MongoDB
mongoose.connect('mongodb://localhost/rest_test');
var autoIncrement = require('mongoose-auto-increment');
// Express
var app = express();
app.use(methodOverride('_method'));
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Routes
app.use('/api', require('./routes/api'));
// Start server
app.listen(4000);
console.log('API is running on port 4000');
angular function to update the data
$scope.updateData = function (userID) {
$scope.actionData = {
"name": $scope.name,
"college": $scope.college,
"age": $scope.age
}
RoleEditF.updateUserData({
userId: userID
}, $scope.actionData).then(function (response) {
$scope.userData = response;
console.log($scope.userData)
$scope.getData();
}).catch(function (response) {
$scope.error = "Unable to get Files (code: " + response.status + "). Please try later.";
});
}
angular.module('myapp')
.factory('RoleEditF', function (updateS) {
return {
updateUserData: function (parm, data, callback) {
var cb = callback || angular.noop;
return updateS.save(parm, data,
function (res) {
return cb(res);
},
function (err) {
return cb(err);
}.bind(this)).$promise;
}
}
})
Factory to call API
angular.module('myapp')
.factory('updateS',function($resource) {
return $resource('http://localhost:4000/api/products/:userId', { userId: '#userId' }, {
update: {
method: 'PUT'
}
}, {
stripTrailingSlashes: false
});
});
I'm getting following error on browser
"NetworkError: 404 Not Found - http://localhost:4000/api/products/57161e0fe4fbae354407baa3"
it has to be 'update' in
'update': {
method: 'PUT'
}
inside your $resource() factory
documentation here
https://docs.angularjs.org/api/ngResource/service/$resource
under Creating a custom 'PUT' request
I am building my website with Angularjs and I am testing it with Node js and express. So, I am able to send a json item with information from the contact page form. But, I do not know How to return a success or fail code from Node.js to Angularjs to redirect to a thank you page. Also, I need to know how to send the information to my email and save it to a db and how to add a token for the form. I know that I'm using the MEAN stack. I learn better watch.
Here is my Node js:
var express = require('express');
var app = express();
var formidable = require('formidable');
app.use(express.static(__dirname + '/public')); // navigate to where the app reside
app.get('/', function (request, response) {
response.redirect('Index.html');
});
app.post('/Contact', function (request, response) {
var frm = new formidable.IncomingForm();
frm.parse(request, function(err, formData){
var Name = formData.Name,
Email= formData.Email,
Message = formData.Message;
response.writeHead(200, { "Content-Type": "application/json" });
response.end("{'status:' 200}");
});
});
var port = 8080;
app.listen(port);
console.log('Listening on port: ' + port);
and here is my Angularjs:
$scope.submit = function () {
console.log('Im in the controller');
console.log($scope.formData);
$http({
method : 'POST',
url : '/Contact',
data : $.param($scope.formData),
headers : { 'Content-Type': 'application/json' }
}).success(function(result, status, headers, config) {
console.log(result);
if(result.status == "???"){
redirectTo: '/Thnkyu';
}
}).error(function(result, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log(result);
});
}
When I submit the form; the console showed: TypeError: Cannot read property 'protocol' of undefined Before it showed: ERR_CONNECTION_REFUSED because I had the url portion before I setted the headers and data.
The problem was I use the angularJs $http dependence as shown above; but, it did not work. So, I use the $http dependence like so:
$scope.submit = function () {
console.log($scope.formData);
$http.post("/contact", $scope.formData)
.success(function(reponse){
if(reponse.status == 200)
console.log('im in')
$location.path('/thnkyu');
});
and the response from the server is like this:
...
if(!eor){
console.log(eor);
response.json({status: 200});
}
var app = angular.module('app', ['ngResource']);
app.factory('UserFactory', function ($resource) {
return $resource('/com/vsoft/rest/users', {}, {
query: {
method: 'GET',
params: {},
isArray: false
}
});
});
app.controller('MyCtrl1', ['$scope', 'UserFactory', function ($scope, UserFactory) {
UserFactory.get({}, function (userFactory) {
$scope.firstname = userFactory.firstName;
$scope.lastname = userFactory.lastName;
});
});
}]);
i added above app in my html.But the app and angular-resource.js but my app.js is not exeuting.
If i removed ngResource module and $resource alert is coming.But if i used ngResource im nt getting alert.
Please help in this.If any one knows any Good Example to use Restful services with angularjs .Please Kindly send Url or code.
Please help me.
i called{{firstname}}
in my html but its not coming .
I use a service for handling RESTful messages
app.service('restService', function ($http, $log) {
'use strict';
var self = this;
var BASE_URL = "base/url/";
//First way how to do it
self.httpGet = function (url) {
$log.info("HTTP Get", url);
return postProcess($http({method: 'GET', url: BASE_URL + url}));
};
//Second way how to do it
self.httpPut = function (url, object) {
$log.info("HTTP Put", url);
return postProcess($http.put(BASE_URL + url, object));
};
self.httpPost = function (url, object) {
$log.info("HTTP Post", url);
return postProcess($http.post(BASE_URL + url, object));
};
self.httpDelete = function (url) {
$log.info("HTTP Delete", url);
return postProcess($http.delete(BASE_URL + url));
};
function postProcess(httpPromise) {
return httpPromise.then(function (response) {
if (response.status === 200) {
return response;
}
//Other than 200 is not ok (this is application specific)
failure(response);
}, function (response) {
failure(response);
});
}
/**
* Promise for failure HTTP codes
* #param response the HTTP response
*/
function failure(response) {
//Error handling
}
});
usable as
restService.httpGet("categories").then(function (response) {
categoryData = angular.fromJson(response.data);
//Broadcast an event to tell that the data is ready to be used
$rootScope.$broadcast("categoriesReady");
});