How to use the login credentials with php in ionic project - ionic-framework

I want to authenticate the user_name and password field. the user_name and password field is stored in database with php. how to get the data from the server in ionic project.
Thanks in advance.

You can create a service script that can send post data to PHP and receive a JSON response.
Post data should be sent as an object containing element name and values in the following format:
var myObj = {username: 'username', password:'password'};
Below is a service example:
yourApp.service('YourService', function ($q, $http) {
return {
login: function (data) {
var deferred = $q.defer(),
promise = deferred.promise;
$http({
url: 'http://www.example.com/yourPHPScript.php',
method: "POST",
data: data,
headers: {'Content-Type': 'application/json'}
})
.then(function (response) {
if (response.data.error.code === "000") {
deferred.resolve(response.data.appointments);
} else {
deferred.reject(response.data);
}
}, function (error) {
deferred.reject(error);
});
promise.success = function (fn) {
promise.then(fn);
return promise;
};
promise.error = function (fn) {
promise.then(null, fn);
return promise;
};
return promise;
}
};
});
From your login controller you call the following code to use the service (make sure you add the name of the service to your controller declaration)
YourService.login(loginData)
.then(function (data) {
// on success do sthg
}, function (data) {
//log in failed
// show error msg
});

Related

AWS Lambda - MongoDB resource optimization

I'm building facebook chatbot using AWS Lambda and MongoDB. At the moment, my application is pretty simple but I'm trying to nail down the basics before I move onto the complex stuff.
I understand AWS Lambda is stateless but I've read adding below line in handler along with variables initialized outside handler, I don't have to establish DB connection on every request.
context.callbackWaitsForEmptyEventLoop = false;
(I've read this from this article; https://www.mongodb.com/blog/post/optimizing-aws-lambda-performance-with-mongodb-atlas-and-nodejs)
I'm adding my entire code below
'use strict'
const
axios = require('axios'),
mongo = require('mongodb'),
MongoClient = mongo.MongoClient,
assert = require('assert');
var VERIFY_TOKEN = process.env.VERIFY_TOKEN;
var PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
var MONGO_DB_URI = process.env.MONGO_DB_URI;
let cachedDb = null;
let test = null;
exports.handler = (event, context, callback) => {
var method = event.context["http-method"];
context.callbackWaitsForEmptyEventLoop = false;
console.log("test :: " + test);
if (!test) {
test = "1";
}
// process GET request --> verify facebook webhook
if (method === "GET") {
var queryParams = event.params.querystring;
var rVerifyToken = queryParams['hub.verify_token']
if (rVerifyToken === VERIFY_TOKEN) {
var challenge = queryParams['hub.challenge'];
callback(null, parseInt(challenge))
} else {
var response = {
'body': 'Error, wrong validation token',
'statusCode': 403
};
callback(null, response);
}
// process POST request --> handle message
} else if (method === "POST") {
let body = event['body-json'];
body.entry.map((entry) => {
entry.messaging.map((event) => {
if (event.message) {
if (!event.message.is_echo && event.message.text) {
console.log("BODY\n" + JSON.stringify(body));
console.log("<<MESSAGE EVENT>>");
// retrieve message
let response = {
"text": "This is from webhook response for \'" + event.message.text + "\'"
}
// facebook call
callSendAPI(event.sender.id, response);
// store in DB
console.time("dbsave");
storeInMongoDB(event, callback);
}
} else if (event.postback) {
console.log("<<POSTBACK EVENT>>");
} else {
console.log("UNHANDLED EVENT; " + JSON.stringify(event));
}
})
})
}
}
function callSendAPI(senderPsid, response) {
console.log("call to FB");
let payload = {
recipient: {
id: senderPsid
},
message: response
};
let url = `https://graph.facebook.com/v2.6/me/messages?access_token=${PAGE_ACCESS_TOKEN}`;
axios.post(url, payload)
.then((response) => {
console.log("response ::: " + response);
}).catch(function(error) {
console.log(error);
});
}
function storeInMongoDB(messageEnvelope, callback) {
console.log("cachedDB :: " + cachedDb);
if (cachedDb && cachedDb.serverConfig.isConnected()) {
sendToAtlas(cachedDb.db("test"), messageEnvelope, callback);
} else {
console.log(`=> connecting to database ${MONGO_DB_URI}`);
MongoClient.connect(MONGO_DB_URI, function(err, db) {
assert.equal(null, err);
cachedDb = db;
sendToAtlas(db.db("test"), messageEnvelope, callback);
});
}
}
function sendToAtlas(db, message, callback) {
console.log("send to Mongo");
db.collection("chat_records").insertOne({
facebook: {
messageEnvelope: message
}
}, function(err, result) {
if (err != null) {
console.error("an error occurred in sendToAtlas", err);
callback(null, JSON.stringify(err));
} else {
console.timeEnd("dbsave");
var message = `Inserted a message into Atlas with id: ${result.insertedId}`;
console.log(message);
callback(null, message);
}
});
}
I did everything as instructed and referenced a few more similar cases but somehow on every request, "cachedDb" value is not saved from previous request and the app is establishing the connection all over again.
Then I also read that there is no guarantee the Lambda function is using the same container on multiple requests so I made another global variable "test". "test" variable value is logged "1" from the second request which means it's using the same container but again, "cachedDb" value is not saved.
What am I missing here?
Thanks in advance!
In short AWS Lambda function is not a permanently running service of any kind.
So, far I know AWS Lambda works on idea - "one container processes one request at a time".
It means when request comes and there is available running container for the Lambda function AWS uses it, else it starts new container.
If second request comes when first container executes Lambda function for first request AWS starts new container.
and so on...
Then there is no guarantee in what container (already running or new one) Lambda function will be executed, so... new container opens new DB connection.
Of course, there is an inactivity period and no running containers will be there after that. All will start over again by next request.

Error API Facebook - Angular 2 and Ionic 2

I'm working with the facebook API and I need to get the profile data to save it in a database. The code returns fine, but when I try to access the data it shows me error because they are null.
This is my code:
this.fb.login(['public_profile', 'user_friends', 'email'])
.then((res: FacebookLoginResponse) => {
token = res.authResponse.accessToken;
userId = res.authResponse.userID;
if (res.status == 'connected') {
this.fb.api('/' + res.authResponse.userID + '?fields=id,first_name,last_name,gender, email,birthday', [],
function onSuccess(result) {
var name = JSON.stringify(result.first_name);
this.register(name);
},
function onError(error) {
console.log(error);
});
} else {
console.log('Not logged in');
}
}).catch(e => console.log('Error logging into Facebook', e));
When I try to call the register method it generates error because the method does not exist, but this is not true. I also tried to save the result of name to a global variable but when it is to be assigned it shows that it can not assign the variable, ie as if the global variable was not defined.
The solution was to change
function onSuccess(result) {
var name = JSON.stringify(result.first_name);
this.register(name);
},
function onError(error) {
console.log(error);
});
for
(result) => {
var name = JSON.stringify(result.first_name);
this.register(name);
},
(error) => {
console.log(error);
});

How to retrieve `custom_disclaimer_responses` in Facebook lead gen webhook data

I have set up a webhook that gets data submitted from a lead gen ad on Facebook.
In my response I have access to field_data and can see names and email address coming through but can't seem to find where the custom_disclaimer_responses is.
I am using the graph API explorer to send test submissions and getting a successful response
My webhook code is as follows:
exports.webhook = function (req, res, next) {
var lead = req.body.entry[0].changes[0].value;
var leadID = lead.leadgen_id;
var formID = lead.form_id;
var customDisclaimerResponses = lead.custom_disclaimer_responses
fs.readFile(config.token, 'utf8', function(err, data) {
if (err) {
console.log('err', err)
throw err;
}
var content = JSON.parse(data);
if(!content.access_token) {
console.log('Facebook Access Token is invalid.');
res.sendStatus(400);
} else {
FB.options({accessToken: content.access_token});
FB.api('/' + leadID, function (response) {
if(response && response.error) {
console.log('error', response.error);
res.sendStatus(400);
} else {
var fields = response.field_data;
// do stuff here with fields
// Response moved to outside of above function block since Facebook will
// stop sending updates if the webhook starts giving errors repeatedly.
res.sendStatus(200);
}
});
}
});
}
Example of response:
{ created_time: '2016-11-17T09:52:44+0000',
id: '<id>',
field_data:
[ { name: 'email', values: [Object] },
{ name: 'first_name', values: [Object] },
{ name: 'last_name', values: [Object] },
{ name: 'city', values: [Object] },
{ name: 'date_of_birth', values: [Object] }
]
}
I don't use webhooks, but I think this can help you:
You can add the parameter fields=custom_disclaimer_responses to get the data you need.
I re-join collected data (the ones in field_data got without parameter) by user id
This is my PHP code, for example:
$url = "https://graph.facebook.com/v2.9/$leadForm/leads?access_token=".$appToken;
$urlCustom = "https://graph.facebook.com/v2.9/$leadForm/leads?fields=custom_disclaimer_responses&access_token=".$appToken;

Protractor: Getting undefined while trying to return a value

I have written a function which sends a GET request and returns the response.
this.generateToken = function() {
var options = {
uri: 'http://localhost:10000/token',
method: 'GET',
headers: {
'Authorization': "YWRtaW46YWRtaW4="
},
};
request(options, function (error, response, body) {
var messageresponse = response.body.toString();
console.log(messageresponse); //I am able to print the response
return messageresponse;
});
};
I am able to print the value of 'messageresponse' variable inside request().
This function is being called from one of my test:
it('Post a GET request and generate a response', function () {
var response = commonFunctionObj.generateToken();
response.then(function(value){ //Getting below mentioned error on this line
console.log(value);
});
});
Getting error: TypeError: Cannot read property 'then' of undefined in teh calling function.
Can someone please help?
You need to create a promise and resolve it once to receive the response.
Look at the below code.
this.generateToken = function() {
var deffered = protractor.promise.defer(); //create a promise
var options = {
uri: 'http://localhost:10000/token',
method: 'GET',
headers: {
'Authorization': "YWRtaW46YWRtaW4="
},
};
request(options, function (error, response, body) {
var messageresponse = response.body.toString();
console.log(messageresponse);
deffered.fulfill(messageresponse); //Instead of returning the response message, fulfill the promise that we created early.
});
return deffered.promise; //return the created promise.
};
Now you can call the generateToken() method inside any of your test that will return a promise which is resolved only when the response is recieved from API call.
it('Post a GET request and generate a response', function () {
var response = commonFunctionObj.generateToken();
response.then(function(value){
console.log(value);
});
});
I think you can do it as follows;
this.generateToken = function() {
var deferred = protractor.promise.defer();
var options = {
uri: 'http://localhost:10000/token',
method: 'GET',
headers: {
'Authorization': "YWRtaW46YWRtaW4="
},
};
request(options, function (error, response, body) {
var messageresponse = response.body.toString();
deferred.fulfill(messageresponse);
});
return deferred.promise;
};
it('Post a GET request and generate a response', function () {
var response = commonFunctionObj.generateToken();
response.then(function(value){ //Getting below mentioned error on this line
console.log(value);
});
});
Explanation;
You can't use .then with generateToken's return. Because there is no return inside of that function. You need to make a promise (protractor.promise) for using then inside of that. Then, you can use .then with generateToken function.
You need to write print response logic in callback function, which is to resolve the promises or handling Asynchronous behavior
Code Snippet:
it('Post a GET request and generate a response', function () {
var response = commonFunctionObj.generateToken(function(err,res){
res.then(function(value){
console.log(value); //or return value
});
});
});

How to catch a 401 (or other status error) in an angular service call?

Using $http I can catch errors like 401 easily:
$http({method: 'GET', url: 'http://localhost/Blog/posts/index.json'}).
success(function(data, status, headers, config) {
$scope.posts = data;
}).
error(function(data, status, headers, config) {
if(status == 401)
{
alert('not auth.');
}
$scope.posts = {};
});
But how can I do something similar when using services instead. This is how my current service looks:
myModule.factory('Post', function($resource){
return $resource('http://localhost/Blog/posts/index.json', {}, {
index: {method:'GET', params:{}, isArray:true}
});
});
(Yes, I'm just learning angular).
SOLUTION (thanks to Nitish Kumar and all the contributors)
In the Post controller I was calling the service like this:
function PhoneListCtrl($scope, Post) {
$scope.posts = Post.query();
}
//PhoneListCtrl.$inject = ['$scope', 'Post'];
As suggested by the selected answer, now I'm calling it like this and it works:
function PhoneListCtrl($scope, Post) {
Post.query({},
//When it works
function(data){
$scope.posts = data;
},
//When it fails
function(error){
alert(error.status);
});
}
//PhoneListCtrl.$inject = ['$scope', 'Post'];
in controller call Post like .
Post.index({},
function success(data) {
$scope.posts = data;
},
function err(error) {
if(error.status == 401)
{
alert('not auth.');
}
$scope.posts = {};
}
);
Resources return promises just like http. Simply hook into the error resolution:
Post.get(...).then(function(){
//successful things happen here
}, function(){
//errorful things happen here
});
AngularJS Failed Resource GET
$http is a service just like $resource is a service.
myModule.factory('Post', function($resource){
return $http({method: 'GET', url: 'http://localhost/Blog/posts/index.json'});
});
This will return the promise. You can also use a promise inside your factory and chain that so your factory (service) does all of the error handling for you.