Need to navigate to other view as soon as Scan completes
Using Zxing with ZXingScannerView
Using this code
scannerView.StartScanning(async (result) =>
{
if (!ContinuousScanning)
{
Console.WriteLine("Stopping scan...");
Console.WriteLine("Result: " + result.Text);
scannerView.StopScanning();
if (result != null)
{
await GetScannedDetails(result.Text);
// here i need to navigate to other screen
}
}
var evt = this.OnScannedResult;
if (evt != null) evt(result);
}, this.ScanningOptions);
When i tried navigating I got this error
Consistency error: you are calling a UIKit method that can only be invoked from the UI thread.
The issue you are having is, you try to run UI related code inside async task. Do the navigation inside main thread
BeginInvokeOnMainThread(
() =>
{
scannerView.StopScanning();
// Navigate code goes here
});
Related
I have attached a screenshot of what I am trying to do. This is so basic yet so frustrating. I have to run a data parse after retrieving the array of objects from the first method being called but I can't add my method to the one inside ngOnInit or directly after it inside ngOnInit. Either way the method just simply doesn't run. Any ideas?
Image
ngOnInit() {
this.getSiteContent(this.route.snapshot.params['id']);
//Doesnt work
this.addUpdatedPages();
}
//in use
getSiteContent(id) {
this.http.get('/site-content/'+id).subscribe(data => {
this.siteContent = data;
});
//Doesn't show..
console.log('End of getSiteContent');
}
addUpdatedPages(){
//Doesn't show
console.log('Adding pages...');
for (var i = 0; i < this.siteContent.length; i++) {
this.checkNull(this.siteContent[i].SiteID, this.siteContent[i].SitePageID);
console.log(this.nullCheck[0].SiteID);
if (this.nullCheck.length > 0) {
this.siteContent[i].SitePageContent = this.nullCheck[0].SitePageContent;
}
}
}
Everything points to an unhandled exception when you call this.http.get. You should check your browsers console, that would show it if there was one. One likely reason is that http was not injected or is undefined.
ngOnInit() {
this.getSiteContent(this.route.snapshot.params['id']);
// if the above throws an exception anything below would not be called
this.addUpdatedPages();
}
getSiteContent(id) {
this.http.get('/site-content/'+id).subscribe(data => {
this.siteContent = data;
});
// If the call above to this.http.get throws an exception the code below would not be called
console.log('End of getSiteContent');
}
That being said the method addUpdatedPages should be called in the subscribe of the http.get because you want it to occur after the data base been retrieved. Modify the getSiteContent so that the line is moved into the callback for the observable's subscribe call.
this.http.get('/site-content/'+id).subscribe(data => {
this.siteContent = data;
this.addUpdatedPages();
});
I'm using React and Node to build an web-based interface to modify data in a Firebase database. I've previously used the Firebase Web SDK in this app to load data from the database, but I've encountered a strange issue with saving a user's changes. When I call set on a database reference (i.e. firebase.database().ref('/path/to/object').set({abc: 'xyz'})), the webpage hangs. Oddly enough, the changes are saved to the database, but the callbacks specified with then are never called (depending on the browser, a This page is slowing down your browser message appears). I'm certain that the issue is related to set as removing the call removes the hang (see save() in my code below).
import React from 'react'
import * as firebase from 'firebase'
// additional (unrelated) imports
export default class Editor extends React.Component {
constructor(props) {
super(props)
this.state = {
savingModal: false,
errorModal: false,
cancelModal: false,
errors: []
}
}
save() {
// this.form is a Reactstrap Form
// validate is a function that returns an array of strings
var errors;
// validate the form, show the errors if any
if ((errors = this.form.validate()) && errors.length > 0)
this.setState({errorModal: true, errors: errors})
else {
// collect is a function that returns an object with the data that the user entered
var x = this.form.collect()
// getEditorInfo is a function that returns info such as the type of object being edited
var info = this.getEditorInfo()
firebase.database().ref(`/${info.category}/${x.id}/`).set(x).then(() => {
this.closeEditor()
}, e => {
alert(`An unexpected error occurred:\n${e}`)
})
this.setState({savingModal: true})
}
}
// closes the window or redirects to /
closeEditor() {
if (window.opener)
window.close()
else
window.location.href = '/'
}
render() {
// BasicModal is a custom component that renders a Reactstrap Modal
// IndeterminateModal is a custom component that renders a Reactstrap Modal with only a Progress element
// EditorToolbar and EditorForm are custom components that render the UI of the page (I don't think they're relevant to the issue)
var info = this.getEditorInfo()
if (!info)
return <BasicModal isOpen={true} onPrimary={this.closeEditor} primary="Close" header="Invalid Request" body="ERROR: The request is invalid."/>
else
return <div>
<EditorToolbar onSave={this.save.bind(this)} onCancel={() => this.setState({cancelModal: true})}/>
<EditorForm ref={f => this.form = f}/>
<BasicModal toggle={() => this.setState({cancelModal: !this.state.cancelModal})} isOpen={this.state.cancelModal} header="Unsaved Changes" body={<p>If you close this window, your changes will not be saved.<br/>Are you sure you want to continue?</p>} primary="Close Anyway" primaryColor="danger" secondary="Go Back" onPrimary={this.closeEditor}/>
<IndeterminateModal style={{
top: '50%',
transform: 'translateY(-50%)'
}} isOpen={this.state.savingModal} progressColor="primary" progressText="Processing..."/>
<BasicModal toggle={() => this.setState({errorModal: false, errors: []})} isOpen={this.state.errorModal} header="Validation Error" body={<div><p>Please resolve the following errors:<br/></p><ul>{(this.state.errors || []).map(e => <li key={e}>{e}</li>)}</ul></div>} primary="Dismiss" primaryColor="primary"/>
</div>
}
}
UPDATE 1/8/2018
I came across this article today and I decided to try a new solution involving JavaScript's setTimeout method. In my situation, the freeze occurred after calling this.setState in my app then calling firebase.database().ref(path).set(data). I suspect the freezing issue was caused by this. I guess JavaScript couldn't handle the state change and Firebase operation all at once. This new solution is functional, more secure, faster, and simpler. Take a look:
// to perform your desired Firebase operation:
var timeout = 50 // give JS some time (e.g. 50ms) to finish other operations first
setTimeout(() => firebase.database().ref(path).set(data).then(
() => {/* ... */},
error => {/* ... */}),
timeout)
OLD SOLUTION
I ended up finding a solution. I'm sure it could be improved, but it works. I used the Web Workers API to run my Firebase code.
Create a new JavaScript file in your public folder (Node.js)
Download a copy of the Firebase web SDK source and place it in public
I chose to communicate with my Worker with postMessage
FirebaseWorker.js
self.onmessage = event => {
importScripts('./firebase.js') // import the local Firebase script
firebase.initializeApp({/* your config */})
const promise = p => p.then(
() => self.postMessage({error: null}),
e => self.postMessage({error: e})
const doWork = () => {
switch (event.data.action) {
case 'get':
promise(firebase.database().ref(event.data.path).once('value'))
break;
case 'set':
promise(firebase.database().ref(event.data.path).set(event.data.data))
break;
case 'update':
promise(firebase.database().ref(event.data.path).update(event.data.data))
break;
case 'remove':
promise(firebase.database().ref(event.data.path).remove())
break;
}
}
if (!firebase.auth().currentUser)
firebase.auth().signInWithEmailAndPassword(event.data.email, event.data.password).then(() => doWork())
else
doWork()
}
To use the Worker:
var worker = new Worker('FirebaseWorker.js')
worker.onmessage = event => {
if (event.data.error)
alert(event.data.error)
// ...
}
worker.postMessage({
data: {/* your data (required if set or update is used) */},
path: '/path/to/reference',
action: 'get, set, update, or remove',
email: 'someone#example.com',
password: 'password123'
})
I'm making an electron desktop app. I want to disable windows key and function keys while the app is on
I tried using the following code ... it registers the event but the windows menu opens anyways
$(document).keydown(function(e){
if (e.keyCode == 37) {
alert( "windows key pressed" );
return false;
}
});
Any help?
You can try this, but unforunately it will become a global shortcut, meaning when the window doesn't have focus it will still be registered. Try putting a console.log() to see when it fires. win is your electron window variable
const {app, globalShortcut} = require('electron');
win = new BrowserWindow();
globalShortcut.register('Super', () => {
if (win.isFocused()) {
// do something
}
});
You can check the docs here: docs
Or try to use this module here: electron-localshortcut
electronLocalshortcut.register(win, 'Super', () => {
console.log('Windows Button pressed');
return false;
});
I have a Chrome extension (specifically, a "content script") where I'd like to detect whether the page I am monitoring/changing is in fullscreen state. I have tried several APIs, as well as the "screenfull" library, but no luck so far. Any ideas?
Thanks for your help!
If you want to detect whether the page has used the Fullscreen API to enter fullscreen mode, just check document.webkitIsFullscreen.
If you want a general method to reliably detect full screen mode, the chrome.windows API is your only option. Since this API is unavailable to content scripts, you need to use the message passing API to interact with a background or event page.
Example: content script
function isFullScreen(callback) {
chrome.runtime.sendMessage('getScreenState', function(result) {
callback(result === 'fullscreen');
});
}
// Example: Whenever you want to know the state:
isFullScreen(function(isFullScreen) {
alert('Window is ' + (isFullScreen ? '' : 'not ') + 'in full screen mode.');
});
Example: background / event page
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message === 'getScreenState') {
chrome.windows.get(sender.tab.windowId, function(chromeWindow) {
// "normal", "minimized", "maximized" or "fullscreen"
sendResponse(chromeWindow.state);
});
return true; // Signifies that we want to use sendResponse asynchronously
}
});
You can try something like this:
var isFullScreen = (screen.width == window.outerWidth) && (screen.height == window.outerHeight);
if(isFullScreen) {
// ...
}
The simplest way is to listen for webkitfullscreenchange event, e.g
$(document).on('webkitfullscreenchange',function(){
if (document.webkitIsFullScreen === true) {
console.log('Full screen mode is on");
} else {
console.log('Full screen mode is off");
}
});
Specifically when doing MonoDroid uses of threads all the documentation I can find recommends calling RunOnUiThread() to call the callback. There is a similar function that can be used on MonoTouch however both of them require a GUI (Activity or whatever its counter part is on IOS). What I would like is to be able to start a thread, pass in a callback and call that callback on the thread that started the thread. For example
ThreadPool.QueueUserWorkItem(state =>
{
//Do Stuff
execute_callback_magically_on_main_thread(() => callback(response));
});
Any ideas? To be clear I would prefer this to not need a handle to the Activity etc.
What if you do something like this? (assuming they have the same signature) I haven't messed with RunOnUiThread, so I don't know it's signature.
public delegate void InvokeOnUIMethod(Action action);
public void CallingMethod()
{
//iOS
MyMethod(InvokeOnMainThread, () => { /* Your callback functionality */ });
//Android
MyMethod(RunOnUiThread, () => { /* Your callback functionality */ });
}
public void MyMethod(InvokeOnUIMethod execute_callback_magically_on_main_thread, Action callback)
{
System.Threading.ThreadPool.QueueUserWorkItem(state =>
{
//Do Stuff
execute_callback_magically_on_main_thread(() => callback(response));
});
}
I hope this helps.
Using the Alpha builds (Hopefully soon to be available as stable) you can use the new Async await idiom.
here is an overview on MSDN:
http://msdn.microsoft.com/en-gb/library/vstudio/hh191443.aspx
and here is a great video series on Channel9:
http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
I found a solution that works and does not appear to be dependent on either platform.
Task<string> t = new Task<string>(() =>
{
//Do Stuff
return "my results";
});
t.ContinueWith(task =>{
if(callback != null)
callback(task.Result);
}, TaskScheduler.FromCurrentSynchronizationContext());
t.Start();
The important part is the TaskScheduler.FromCurrentSynchronizationContext() which tells the "ContinueWith" to execute on the original thread.