How to access Flutter Back button functionality? - function

I would like to present an AdWords interstitial before the user returns to the previous page. How can I do this when the return button is pressed?

I think you can make use of WillPopScope widget. You can pass a callback function which will be called when the view is about pop. Just do whatever tasks to be completed before pop and then return true.
Example:
Future<bool> _willPopCallback() async {
// await showDialog or Show add banners or whatever
// then
return true; // return true if the route to be popped
}
//then pass the callback to WillPopScope
new WillPopScope(child: new Scaffold(), onWillPop: _willPopCallback)

Related

Angular service/factory return after getting data

I know this has something to do with using $q and promises, but I've been at it for hours and still can't quite figure out how it's supposed to work with my example.
I have a .json file with the data I want. I have a list of people with id's. I want to have a service or factory I can query with a parameter that'll http.get a json file I have, filter it based on the param, then send it back to my controller.
angular
.module("mainApp")
.controller('personInfoCtrl',['$scope', '$stateParams', 'GetPersonData', function($scope, $stateParams, GetPersonData) {
$scope.personId = $stateParams.id; //this part work great
$scope.fullObject = GetPersonData($stateParams.id);
//I'm having trouble getting ^^^ to work.
//I'm able to do
//GetPersonData($stateParams.id).success(function(data)
// { $scope.fullObject = data; });
//and I can filter it inside of that object, but I want to filter it in the factory/service
}]);
Inside my main.js I have
//angular.module(...
//..a bunch of urlrouterprovider and stateprovider stuff that works
//
}]).service('GetPersonData', ['$http', function($http)
{
return function(id) {
return $http.get('./data/people.json').then(function(res) {
//I know the problem lies in it not 'waiting' for the data to get back
//before it returns an empty json (or empty something or other)
return res.data.filter(function(el) { return el.id == id)
});
}
}]);
The syntax of the filtering and everything works great when it's all in the controller, but I want to use the same code in several controls, so I'm trying to break it out to a service (or factory, I just want the controllers to be 'clean' looking).
I'm really wanting to be able to inject "GetPersonData" to a controller, then call GetPersonData(personId) to get back the json
You seems to be syntax issue in your filter function in the service.
.service('GetPersonData', ['$http', function($http){
return function(id) {
return $http.get('./data/people.json').then( function (res) {
return res.data.filter(function(el) { return el.id == id });
});
}}]);
But regarding the original issue you cannot really access the success property of the $q promise that you are returning from your function because there is no such property exist, It exists only on the promise directly returned by the http function. So you just need to use the then to chain it through in your controller.
GetPersonData($stateParams.id).then(function(data){ $scope.fullObject = data; });
If you were to return return $http.get('./data/people.json') from your service then you will see the http's custom promise methods success and error.

A solution for streaming JSON using oboe.js in AngularJS?

I'm pretty new to Angular so maybe I'm asking the impossible but anyway, here is my challenge.
As our server cannot paginate JSON data I would like to stream the JSON and add it page by page to the controller's model. The user doesn't have to wait for the entire stream to load so I refresh the view fo every X (pagesize) records.
I found oboe.js for parsing the JSON stream and added it using bower to my project. (bower install oboe --save).
I want to update the controllers model during the streaming. I did not use the $q implementation of pomises, because there is only one .resolve(...) possible and I want multiple pages of data loaded via the stream so the $digest needs to be called with every page. The restful service that is called is /service/tasks/search
I created a factory with a search function which I call from within the controller:
'use strict';
angular.module('myStreamingApp')
.factory('Stream', function() {
return {
search: function(schema, scope) {
var loaded = 0;
var pagesize = 100;
// JSON streaming parser oboe.js
oboe({
url: '/service/' + schema + '/search'
})
// process every node which has a schema
.node('{schema}', function(rec) {
// push the record to the model data
scope.data.push(rec);
loaded++;
// if there is another page received then refresh the view
if (loaded % pagesize === 0) {
scope.$digest();
}
})
.fail(function(err) {
console.log('streaming error' + err.thrown ? (err.thrown.message):'');
})
.done(function() {
scope.$digest();
});
}
};
});
My controller:
'use strict';
angular.module('myStreamingApp')
.controller('MyCtrl', function($scope, Stream) {
$scope.data = [];
Stream.search('tasks', $scope);
});
It all seams to work. After a while however the system gets slow and the http call doesn't terminate after refreshing the browser. Also the browser (chrome) crashes when there are too many records loaded.
Maybe I'm on the wrong track because passing the scope to the factory search function doesn't "feel" right and I suspect that calling the $digest on that scope is giving me trouble. Any ideas on this subject are welcome. Especially if you have an idea on implementing it where the factory (or service) could return a promise and I could use
$scope.data = Stream.search('tasks');
in the controller.
I digged in a little further and came up with the following solution. It might help someone:
The factory (named Stream) has a search function which is passed parameters for the Ajax request and a callback function. The callback is being called for every page of data loaded by the stream. The callback function is called via a deferred.promise so the scope can be update automatically with every page. To access the search function I use a service (named Search) which initially returns an empty aray of data. As the stream progresses the factory calls the callback function passed by the service and the page is added to the data.
I now can call the Search service form within a controller and assign the return value to the scopes data array.
The service and the factory:
'use strict';
angular.module('myStreamingApp')
.service('Search', function(Stream) {
return function(params) {
// initialize the data
var data = [];
// add the data page by page using a stream
Stream.search(params, function(page) {
// a page of records is received.
// add each record to the data
_.each(page, function(record) {
data.push(record);
});
});
return data;
};
})
.factory('Stream', function($q) {
return {
// the search function calls the oboe module to get the JSON data in a stream
search: function(params, callback) {
// the defer will be resolved immediately
var defer = $q.defer();
var promise = defer.promise;
// counter for the received records
var counter = 0;
// I use an arbitrary page size.
var pagesize = 100;
// initialize the page of records
var page = [];
// call the oboe unction to start the stream
oboe({
url: '/api/' + params.schema + '/search',
method: 'GET'
})
// once the stream starts we can resolve the defer.
.start(function() {
defer.resolve();
})
// for every node containing an _id
.node('{_id}', function(node) {
// we push the node to the page
page.push(node);
counter++;
// if the pagesize is reached return the page using the promise
if (counter % pagesize === 0) {
promise.then(callback(page));
// initialize the page
page = [];
}
})
.done(function() {
// when the stream is done make surethe last page of nodes is returned
promise.then(callback(page));
});
return promise;
}
};
});
Now I can call the service from within a controller and assign the response of the service to the scope:
$scope.mydata = Search({schema: 'tasks'});
Update august 30, 2014
I have created an angular-oboe module with the above solution a little bit more structured.
https://github.com/RonB/angular-oboe

Chrome extension - pass function result from content script to popup.js

I have extension with popup.html which has popup.js in it.
I use popup.js to call function located in content script using chrome.tabs.sendMessage -method.
This is working nicely, but..
How do I return the value of the function back to popup.js ? Do I need to set up a listener on the popup.js aswell or what ?
On my popup.js I have:
chrome.tabs.sendMessage(tab.id, {
expiryRequest: 'expiry '
}, function (response) {
if (response.refreshResponse === true) {
console.log('Expiry taken');
} else {
console.log('Expiry NOT taken');
}
});
This part works great..
On my content script I read certain div into a vartiable "result".
At the end of the function on content script I have used.
return result;
or
return true;
None of those returns anything back tuo popup.js.
What do I need to change in order to get my return to work from content script to popup.js ?
You should not return your result, but send it back.
chrome.runtime.onMessage callbacks take 3 parameters: the message, the sender information, and the sendResponse callback.
To pass a response back, sendResponse must be called:
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
if(message.ping) sendResponse({pong: true});
});
However, there's an additional trick to it. The event listener should either reply immediately (i.e. synchronously, before it exits) or signal that it will reply later. This is done with the return value:
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
if(message.ping) {
chrome.storage.local.get("shouldReply", function(result){
// This is asynchronous: by now the listener returned
if(result.shouldReply) sendResponse({pong: true});
});
}
return true; // Indicate that you will eventually call sendResponse
});
Unless you do this, sendResponse reference is invalidated when the listener exits and an undefined response is sent.
One more caveat: you should call sendResponse no more than once; it will generate an error otherwise.

Message Dialog in Windows Store WITHOUT Async?

So, I'm porting an app over to Windows Store. At the start of the app, I have some code, that asks a question. I DO NOT WANT THE REST OF MY CODE TO FIRE UNTIL I GET A RESPONSE.
I have this:
string message = "Yadda Yadda Yadda";
MessageDialog msgBox = new MessageDialog(message, "Debug Trial");
msgBox.Commands.Add(new UICommand("OK",
(command) => { curSettings.IsTrial = true; }));
msgBox.Commands.Add(new UICommand("Cancel",
(command) => { curSettings.IsTrial = false; }));
await msgBox.ShowAsync();
//... more code that needs the IsTrial value set BEFORE it can run...
When I run the app, the code after the msgBox.ShowAsync() runs, without the correct value being set. It's only after the method finishes that the user sees the Dialog box.
I would like this to work more like a prompt, where the program WAITS for the user to click BEFORE continuing the method. How do I do that?
MessageDialog does not have a non-asynchronous method for "Show." If you want to wait for the response from the dialog before proceeding, you can simply use the await keyword.
Here also is a quickstart guide for asynchronous programming in Windows Store Apps.
I see that your code sample already uses "await". You must also mark the calling function as "async" in order for it to work properly.
Example:
private async void Button1_Click(object sender, RoutedEventArgs e)
{
MessageDialog md = new MessageDialog("This is a MessageDialog", "Title");
bool? result = null;
md.Commands.Add(
new UICommand("OK", new UICommandInvokedHandler((cmd) => result = true)));
md.Commands.Add(
new UICommand("Cancel", new UICommandInvokedHandler((cmd) => result = false)));
await md.ShowAsync();
if (result == true)
{
// do something
}
}

How to synchronize returning function values in jQuery?

I have written this function in jQuery:
function checkAvailability(value) {
var result = true;
$.getJSON("registration/availability", { username: value }, function(availability) {
if (!availability)
result = false;
alert("in getJSON: " + result);
});
alert(result);
return result;
}
I have got alert from 'getJSON' after this second. Why has it happened this way?
I have Spring MVC project and Controller method which checks username availability. Controller method works properly. But I receive final result too late. How can I synchronize it to return properly value in my function?
EDIT
I am using this function in jQuery validate. I have extracted checkAvailability() function during my test.
$.validator.addMethod("checkAvailability", function(value, element, param) {
var das = checkAvailability(value);
return das;
}, jQuery.format("Someone already has that username. Please try another one."));
And this is my form validate:
$(".form").validate({
rules: {
username: {
checkAvailability: true
},
....
},
messages: {
}
});
EDIT 2
This is my Controller method. It returns boolean value. If username was taken it would return false value.
#RequestMapping(value="/registration/availability", method = RequestMethod.POST)
public #ResponseBody boolean getAvailability(#RequestParam String username) {
List<User> users = getAllUsers();
for (User user : users) {
if (user.getUsername().equals(username)) {
return false;
}
}
return true;
}
Why does this behave this way?
$.getJSON is shorthand for making an AJAX request. The 'A' in ajax stands for asynchronous. Meaning, the javascript engine fires the getJSON call and then immediately executes the next lines, which is alert(result); return result;
The actual value as returned by the web service will be received by your code at a later point in time. The success function that you passed into getJSON will be called once the js engine receives the response from the server. As you can see, it is too late by that point.
Further reading: https://developer.mozilla.org/en/AJAX
What can I do to make this work?
That depends on your situation. Who is calling checkAvailabilty? If you post some code on how this function is being used, I can give examples with my suggestions.
Off the top of my head, you could either make use of jquery deferreds, nice article on the same. Or you could pass in a callback function that is executed from inside your success function.
EDIT:
http://docs.jquery.com/Plugins/Validation/Methods/remote#options
The serverside resource is called via $.ajax (XMLHttpRequest) and gets
a key/value pair, corresponding to the name of the validated element
and its value as a GET parameter. The response is evaluated as JSON
and must be true for valid elements, and can be any false, undefined
or null for invalid elements,
To get a real world idea, check the demo http://jquery.bassistance.de/validate/demo/captcha/
Open Firebug or the developer tools of your choice. Go to the tab that lets you see AJAX requests. Enter the captcha, submit. Check ajax request as listed in the developer tool. Notice the query string parameters. Notice the response. Its a simple 'true' or 'false'.
Not sure if this helps or not but you can use
var result;
$.ajax( {
url : "registration/availability",
data : data,
async : false //syhcrononous ajax request ;)
}).done(function(data) {
result = data;
});
for more info you can refer JQuery AJAX doc