How to run http call as background in ionic Framework? - ios

I am using ionic Framework. i have multiple HTTP service which is working fine. Now problem is that whenever i get response of any http call. i can't proceed further.
Can we run HTTP Service as a background process. So my application continues works without waiting for result.
here is my code
articleService.getArticles().then(function() {
},function(err){
});
and sercvice code
$http({
url: "http://myservice.com",
data: { user_id: 1 },
method: 'POST',
withCredentials: true,
}).success(function (data) {
deferred.resolve(data);
}).error(function (err) {
deferred.resolve(0);
})
return deferred.promise;
}
Any idea? I need a solution in ionic framework which will work both for ios and andriod?
Thanks

try to use html5 web workers what u need to do is multithreading and because that javascript is single threading environment you have to web workers
https://html.spec.whatwg.org/multipage/workers.html

Look at this plunker this what you need and it is all angularjs so will work with ionic.
var app = angular.module('angularjs-starter', []);
app.config(function($routeProvider) {
$routeProvider.
when('/', {controller:'StartCtrl', templateUrl:'start.html'}).
when('/main', {controller:'MainCtrl', templateUrl:'main.html'}).
otherwise({redirectTo:'/'});
});
app.controller('MainCtrl', function($scope, Poller) {
$scope.name = 'World';
$scope.data = Poller.data;
});
app.controller('StartCtrl',function(){});
app.run(function(Poller) {});
app.factory('Poller', function($http, $timeout) {
var data = { response: {}, calls: 0 };
var poller = function() {
$http.get('data.json').then(function(r) {
data.response = r.data;
data.calls++;
$timeout(poller, 1000);
});
};
poller();
return {
data: data
};
});

Maybe i misunderstand your question but i think your service code is wrong.
Try something like this
myApp.factory('articleService', function($http) {
return {
getArticles: function getArticles() {
return $http({...}); // $http returns a promise, so you dont need your own defer.promise
}
}
});
//usage
//first: send or get data async
articleService.getArticles().then(function(resp){
alert('called second');
...
});
// second: do something else, this will not wait for your response
alert('called first');

Related

Amazon Lex- slot elicitation not working inside callback

I have a call back function which is getting data from an external API and depends on a data check I have tried for a slot elicitation inside callback but looks like elicitation is not working inside the callback. Please find the code snippet below,
GetCustomerDetails().then(response => {
var serializedcustomerDetails = convert.xml2json(response.data, {
compact: true,
spaces: 2
});
var customerDetails = JSON.parse(serializedcustomerDetails);
let filteredCustomerDetails = _.filter(customerDetails.CustomerInfo.CustomerDetails, function (o) {
return o.CustomerName._text.includes(customerName);
})
if (filteredCustomerDetails.length == 1) {
callback(elicitSlot(outputSessionAttributes, intentRequest.currentIntent.name,
intentRequest.currentIntent.slots, '​CustomerCode', {
contentType: 'PlainText',
content: `Do you mean ${filteredCustomerDetails[0].CustomerName._text} of ${filteredCustomerDetails[0].SpecialityName._text} department?`
}));
return;
}
}).catch(error => {
console.log(`${error}`)
})
This is my first Awnser on stack so please bear with me.
I have come accross the same problem in a recent project and there are a few things that you can check.
How long does the API call take?
If your API call takes a long time it will be worth checking the timeout settings on your Lambda function. AWS Console -> Lambda -> Your Function -> Basic settings -> Timeout.
Does your Lambda function finish before the API call is done?
I fixed this issue by building a node module to handle my business logic, the module has a function called getNextSlot it returns as a Promise. Inside this function I check the incoming event and figure out which slot I need to elicit next, part of my flow is to call an API endpoint that takes around 10 seconds to complete.
I use the request-promise package to make the api call, this node module makes sure that the lambda function keeps running while the call is running.
exports.getData = function (url, data) {
var pr = require("request-promise");
var options = {
method: 'POST',
url: 'api.example',
qs: {},
headers:
{
'Content-Type': 'application/json'
},
body: {
"example": data
},
json: true,
timeout: 60000
};
return pr(options);
}
In my main code I call this function as:
apiModule.getData("test", "data")
.then(function (data) {
//Execute callback
})
.catch(function (error) {
console.log(error);
reject(error);
});
This solved the issue for me anyways.
Thanks,

PreloadJS and Service Worker

I am trying to use service worker with PreloadJS. I have cached the images required and then loading them using the caches.match() function.
When I try to load the image with jquery it works fine, but on loading with preloadJS it gives the following error
The FetchEvent for "someurl" resulted in a network error response: an "opaque" response was used for a request whose type is not no-cors
Although if I load any other image that isn't cached, PreloadJS loads that image properly. The problem is occuring only when I use caches.match.
What might be the reason for this ?
Load Image using preloadjs
var preload = new createjs.LoadQueue({ crossOrigin: "Anonymous" });
function loadImageUsingPreload() {
preload.on('complete', completed);
preload.loadFile({ id: 'someid', src: 'someurl', crossOrigin: true })
};
function completed() {
var image = preload.getResult("shd");
document.body.append(image);
};
Load Image using jquery
function loadImageUsingJquery() {
jQuery("#image").attr('src', 'someurl');
};
Service Worker fetch event
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
if (!response) {
console.log('fetching...' + event.request.url);
return fetch(event.request);
};
console.log("response", response);
return response;
}));
});
The response object when I load using PreloadJS or jQuery:
Response {type: "opaque", url: "", redirected: false, status: 0, ok: false, …}
Found out the mistake ,
Actually during cache.put I was modifying the request object's mode to 'no-cors' if the origin were not the same.
Now during a fetch event, the event's request object had property 'cors' because it was a cross-origin request.
This difference of value of mode was causing the fetch error.
Service worker install event:
var request = new Request(value);
var url = new URL(request.url);
if (url.origin != location.origin) {
request = new Request(value, { mode: 'no-cors' });
}
return fetch(request).then(function(response) {
var cachedCopy = response.clone();
return cache.put(request, cachedCopy);
});
I changed it to :
var request = new Request(value);
var url = new URL(request.url);
return fetch(request).then(function(response) {
var cachedCopy = response.clone();
return cache.put(request, cachedCopy);
});
I have to use the first method for saving cdn's because second method is not working for them and vice-versa for my images hosted on cloudfront .
I will post the reason when I find why this is happening.

Falcor Router should return the value from external API

I am new to JavaScript frameworks and currently trying to setup a falcor router calling an external api (for now consider it as an express api app + mango db, hosted at 3000 port).
Now, I am able to use the request package (commented out lines) and successfully call the Express Api app (which returns obj.rating = 4). But I am unable to send this value from the falcor router instead of the hard-coded value "5".
Below is the falcor-router's server.js code:
app.use('/rating.json', falcorExpress.dataSourceRoute(function (req, res) {
return new Router([
{
route: "rating",
get: function() {
var obj;
// request('http://localhost:3000/rating/101', function (error, response, body) {
// obj = JSON.parse(body);
// console.log('rating:', obj.rating); // obj.rating = 4
// });
return {path:["rating"], value:"5"};
}
}
]);
}));
The below is the code for index.html:
<script>
function showRating() {
var model = new falcor.Model({source: new falcor.HttpDataSource('http://localhost/rating.json') });
model.
get("rating").
then(function(response) {
document.getElementById('filmRating').innerText = JSON.stringify(response.json,null, 4);
});
}
</script>
I also tried to look at the global variable declaration, synchronize http request calls, promises, then statements etc. But nothing seemed to work, clearly I am missing out something here - not sure what.
The router's get handler expects the return value to be a promise or an observable that resolves to a pathValue. To get your request against the db to work, simply return a promise that resolves to a pathValue, e.g.
return new Router([
{
route: "rating",
get: function() {
return request('http://localhost:3000/rating/101', function (error, response, body) {
return { path: ["rating", value: JSON.parse(body).rating };
});
}
}
]);

$http.post cannot find issue

Good afternoon everyone.
I'm working on a school project to create an application using the MEAN stack, and I'm having issues with routing.
I'm using the login-and-register application found here as a base for my work : http://jasonwatmore.com/post/2015/12/09/mean-stack-user-registration-and-login-example-tutorial
Basically, I am unable to post data that I get from a form I created to my database.
If I get the creation part to work, then I'll be able to continue working on my project. Here is the code :
The Controller
(function () {
'use strict';
function Controller(UserService, NoteService, FlashService) {
var vm = this;
vm.note = null;
function createNote() {
NoteService.Create(vm.note, vm.user)
.then(function () {
FlashService.Success('Note created');
})
.catch(function (error) {
FlashService.Error(error);
});
}
vm.createNote = createNote;
function initController() {...}
initController();
}
angular.module('app').controller('Home.IndexController', Controller);
}());
And then we have the service I'm calling, NoteService
(function () {
'use strict';
function Service($http, $q) {
var service = {};
function Create(note, user) {
return $http.post('/api/notes', note).then(handleSuccess, handleError);
}
service.Create = Create;
return service;
}
angular
.module('app')
.factory('NoteService', Service);
}());
This is the $http.post function that doesn't work : /api/notes cannot be found (error 404 on browser console) I am sure my object note is getting at least to this request, because adding a console.log(note) just before returns what I want in the console.
On the server side, I have another controller for handling errors :
var noteService = require('services/notes.service');
//routes
router.post('/create', createNote);
module.exports = router;
function createNote(req, res) {
noteService.create(req.body)
.then(function () {
res.sendStatus(200);
})
.catch(function (err) {
res.status(400).send(err);
});
}
the service on the server side to discuss with the data base :
var mongo = require('mongoskin');
var db = mongo.db(config.connectionString, { native_parser: true });
db.bind('notes');
var service = {};
service.create = create;
module.exports = service;
function create(noteParam, userParam) {...}
and my server.js file looks like this :
require('rootpath')();
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(session({ secret: config.secret, resave: false, saveUninitialized: true }));
// use JWT auth to secure the api
app.use('/api', expressJwt({ secret: config.secret }).unless({ path: ['/api/users/authenticate', '/api/users/register'] }));
// routes
app.use('/login', require('./controllers/login.controller'));
app.use('/register', require('./controllers/register.controller'));
app.use('/app', require('./controllers/app.controller'));
app.use('/api/users', require('./controllers/api/users.controller'));
app.use('/api/notes', require('./controllers/api/notes.controller'));
// make '/app' default route
app.get('/', function (req, res) {
return res.redirect('/app');
});
// start server
var server = app.listen(3000, function () {
console.log('Server listening at http://' + server.address().address + ':' + server.address().port);
});
I thought this line in the server.js file : app.use('/api/notes', require('./controllers/api/notes.controller'))
would permit my post request to send my note object to the server side, to '/api/notes') but I'm not quite sure how all this works together.
I am hoping anyone can help me, even though the code I gave was lengthful.
I am just beginning with MEAN and have no idea what I'm doing wrong.
Thanks in Advance for your answer.

ionic/AngularJS OK in Chrome, Can't find variable :$ in iOS Simulator

Im currently using Ionic framework (inc AngularJS) with PhoneGap to develop a mobile application.
When running in chrome the application works seamlessly (I have been debugging the errors while in development).
I deployed to the iOS simulator today and hooked it upto safari developer tools and got the follow error.
Error: Can't find variable: $
My controllers etc work fine here however my postLogin() function does not.
Here is a cutdown version of my LoginController, Am i not passing $ correctly?
.controller('LoginCtrl', function($http, $ionicLoading, $scope, $state) {
$scope.login = {};
$scope.handlerLogin = function(response){
$ionicLoading.hide();
if(response.data.response == 1){
localStorage.setItem("token",response.data.token);
$state.go("app.search", {}, {reload: true});
}else if(response.data.response == 0){
$scope.login.password = '';
$('#errorMessageText').text('Login failed. Please try again.');
$('#errorMessage').fadeIn(2000, function(){$('#errorMessage').fadeOut('slow');});
}else{
//handle general error?
}
}
$scope.postLogin = function() {
$ionicLoading.show({
template: 'loading'
});
var formdata = $scope.login;
var url = api + 'api/login';
$.ajax({
type: "GET",
url: url,
data: formdata,
success: function success(data){
$scope.handlerLogin(data);
},
dataType: 'jsonp'
});
};
$scope.doLogin = function() {
if($scope.login.email == null || $scope.login.password == null){
$('#errorMessageText').text('Please complete both fields.');
$('#errorMessage').fadeIn(2000, function(){$('#errorMessage').fadeOut('slow');});
}
else{
$scope.postLogin();
}
}
});
Please ignore than im using JSONP for logging in for now.
Any pointers would be a great help! Scratching my head for hours now!!

Resources