Ionic 2: best way to check if is running in browser environment - javascript

I can't find out in the docs which is the best way to know, in an Ionic 2 app, if it's runnning in the browser (with the ionic serve command) or in the device/emulator.
Actually what I'm doing is check if the window object has an 'plugins' attribute, but I don't know if there is the best way.
if(!window['plugins']) {
//browser
}

Oh, I found in the docs the Platform object, which has some methods.
http://ionicframework.com/docs/v2/api/platform/Platform/
One is the is(key), that can match
import { Platform } from 'ionic-angular';
#Component({...})
export MyPage {
constructor(platform: Platform) {
this.platform = platform;
...
if(this.platform.is('core')) {
//it's in the browser
}
}
}

while the question is a bit old but still valid - one more option is to use
https://ionicframework.com/docs/native/device/ - the Device object provides platform property which is equal to 'browser' on browser. The plugin is available only when running webapp via cordova.

Just to add a little more to the solution given above, the following does seem to work ok:
import { Platform } from 'ionic-angular';
#IonicPage()
#Component({})
export class WhichPlatformPage {
isApp: boolean;
constructor(private platform: Platform) {
this.isApp = this.platform.is('core') || this.platform.is('mobileweb') ? false : true;
}
}
ionViewDidLoad() {
console.log(this.isApp ? 'Running from mobile' : 'Running from the browser');
}
This seems to work fine for me - the main difference from the previous answer is that we are also checking for the 'mobileweb' platform.
Interestingly, if you are using the ionic cordova build browser command, 'mobileweb' becomes 'mobile' - breaking this solution - as this is trying to emulate being on a device as much as possible. This was raised as an issue on GitHub here:
https://github.com/ionic-team/ionic/issues/11557
A solution was given as setting isApp with the following:
this.isApp = !document.URL.startsWith('http');
This works because the mobile apps start their pages with the 'file' protocol. However, if you read into the issue, Ionic are actually recommending against using the cordova browser platform currently, so you would be better off with the original solution.

Thought I'd update with an answer that works in case anyone arrives at this question.
This works as of the latest iOS and Android builds:
public isApp(): boolean {
return (
document.URL.indexOf('http://localhost') === 0 || // Android
document.URL.indexOf('ionic') === 0 || // iOS 11+ Ionic Web View
document.URL.indexOf('https://localhost') === 0 // iOS 10 Ionic Web View
);
}
See Ionic Webview readme for more info and caveats.

I found this solution resolved in Ionic forum which is using
this.isApp = (!document.URL.startsWith('http') || document.URL.startsWith('http://localhost:8080'));
it may have changes in the future releases though as ios/androd new release change comes
details discussed https://forum.ionicframework.com/t/how-to-determine-if-browser-or-app/89149/15

Related

Import typescript files based on naming convention in React Native

So I have three ts files named as below :
MyModule.ios.ts
MyModule.android.ts
MyModule.ts ( this is empty )
first two files have a method named : setup() which need to run based on platform Also metro bundler will do the resolution, it will try to import .ios when building for ios and .android when building for android..
and I have another file which import this method like this :
import { setup } from 'MyModule';
the problem is, I am not sure if this will resolve the .android and .ios files. What is the proper way to do this kind of code splitting?
I find this workaround here but I was wondering if there is a better way : https://github.com/Microsoft/TypeScript/issues/8328#issuecomment-219583152
If you want to use separate files for iOS and Android, you need to call them MyModule.ios.ts and MyModule.android.ts extensions. The empty MyModule.ts file is not necessary.
Then just import them as if they didn't have the platform specific extensions. React Native will automatically pick up the right file based on the running platform.
import { setup } from './MyModule'; // Will automatically import either MyModule.ios.ts or MyModule.android.ts
See the documentation on this: https://facebook.github.io/react-native/docs/platform-specific-code.html#platform-specific-extensions
If you don't want to use separate files, you can use the Platform module. This is nice for small pieces of code that you want to make platform specific.
import { Platform } from 'react-native';
if(Platform.OS === 'ios') {
// iOS specific code here
} else if(Platform.OS === 'android') {
// Android specific code here
} else {
// Other platform
}
See: https://facebook.github.io/react-native/docs/platform-specific-code#platform-module

How to get Android Version number in React-Native? (not API level number)

I want to display the Android Version in my app (like 8.0, 9.0...). For now I am using: Platform.Version But this returns the API version (24, 25...).
I would like an option that's more elegant than just creating a mapping, and that does not require republishing every time there is a new android release.
Is there a way to do that without an external library?
you can :
import { Platform } from 'react-native';
const OsVer = Platform.constants['Release'];
You can use this library,
react-native-device-info
import DeviceInfo from "react-native-device-info";
DeviceInfo.getSystemVersion()
apart from version, it has lots of methods which are much handy for getting device specific information.
EDIT: It is getSystemVersion()
You can use Platform.constants.Release
You have 2 options
Map values you are getting using Platform.Version with appropriate version number.
Use 3rd party library for example react-native-device-info, getSystemVersion
DeviceInfo.getSystemVersion()
Hi check this component
react-native-device-info
check
**Gets the API level.**
**Examples**
getAPILevel()
const apiLevel = DeviceInfo.getAPILevel();
// iOS: ?
// Android: 25
// Windows: ?

DWT Java Script Library Progress Dialogue Automatically Displays with Angular 5

I am incorporating the Dynamic Web Twain javascript library into my angular application to allow my end users to scan using a web browser instead of a desktop application.
Upon loading the page, the progress bar immediately pops up. This is not expected behavior, nor does it happen when I use angular 4. I am using angular 5 at work. It also makes no difference which browser I use (IE, Chrome, Firefox).
The version of my Angular is:
> Angular CLI: 1.6.6 Node: 9.4.0 OS: win32 x64 Angular: 5.2.3 ...
> animations, common, compiler, compiler-cli, core, forms ... http,
> language-service, platform-browser ... platform-browser-dynamic,
> router
>
> #angular/cli: 1.6.6 #angular-devkit/build-optimizer: 0.0.42
> #angular-devkit/core: 0.0.29 #angular-devkit/schematics: 0.0.52
> #ngtools/json-schema: 1.1.0 #ngtools/webpack: 1.9.6
> #schematics/angular: 0.1.17 typescript: 2.5.3 webpack: 3.10.0
I have included the javascript library into my newly created Angular project using these commands:
npm install dwt --save
npm install #type/dwt --save
Also note that my webtwain.min.js is added to the scripts within my angular-cli.json:
"scripts": [
"../node_modules/dwt/dist/dynamsoft.webtwain.min.js"
Here is the layout of my project:
Finally, here is my component.ts file and its related html (it doesn't matter how I populate the html, the result is the same):
/// <reference types="dwt" />
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-scan',
template: '<button (click)="acquireImage()">Scan Document</button><div id="dwtcontrolContainer"></div>',
styleUrls: ['./scan.component.css']
})
export class ScanComponent implements OnInit {
constructor() { }
ngOnInit() {
}
acquireImage(): void {
const dwObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');
dwObject.IfShowIndicator = false;
const bSelected = dwObject.SelectSource();
if (bSelected) {
const onAcquireImageSuccess = () => { dwObject.CloseSource(); };
const onAcquireImageFailure = onAcquireImageSuccess;
dwObject.OpenSource();
dwObject.AcquireImage({}, onAcquireImageSuccess, onAcquireImageFailure);
}
}
}
Finally here is the result:
The 'progressbar' shown with a value of 0% pops up immediately. In angular 4, this does not happen. Any thoughts on what is causing this? I am trying to read up on the changes between 4 and 5, specifically asynchronous and synchronous loading but I am still new to this framework.
Thanks,
Josh
This is Tom from Dynamsoft.
What you posted here is a known issue in v13.3 of the SDK Dynamic Web TWAIN.
Here is the fix
Update CSS (dynamsoft_dwt_html5.css) to add the following
dialog[closed] {
display: none;
}
Update dynamsoft.webtwain.initiate.js to apply the new CSS rule
m.showDialog=function(y){var z=this,v;if(z.open){j.error("showDialog called on open dialog.");return}z.open=i;z.removeAttribute("closed");
m.closeDialog=function(t){var v=this;if(!v.open){j.error("closeDialog called on closed dialog.")}v.open=o;v.removeAttribute("open");v.setAttribute("closed","closed");
y.push('<dialog class="dynamsoft-dwt-dialogProgress" closed="closed" style="top:30%">
Since the code is minimized, it might look different in your own copy of the JS, if you like, you can email our support team (support#dynamsoft.com, if possible, please use your business email address) for the patch. Thanks.
BTW, the patch will be part of v13.4 soon to be released.

Cordova-plugin-contacts leaves navigator.contacts as undefined?

To give some background on my current project - I am working on a phonebook application for employees where there will be a button to create a new contact on the user's device. I am using the following plugin to handle this in my Ionic application:
http://cordova.apache.org/docs/en/latest/reference/cordova-plugin-contacts/
When attempting to access the plugin the way that the documentation states:
navigator.contacts
I had also tried to access via
window.navigator.contacts
It returns an undefined error. In the documentation it states that this will only be accessible after the deviceready event is fired - so my code was the following:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log("Testing Navigation Contacts");
console.log(navigator.contacts);
}
I also tried to utilize the $ionicPlatform.ready functionality as done below:
$ionicPlatform.ready(function() {
var myContact = window.navigator.contacts.create({"displayName": "Test User"});
myContact.save();
});
The exact error message is listed below:
Error: undefined is not an object (evaluating 'navigator.contacts.create')
Any help would be much appreciated, guys. I'm at a loss of what else to try. Thanks for reading!
Mike
I have tried out the plugin and it works as expected. Have tested the same in device running on Android Marshamallow.
Have come up with a sample cordova app that uses this contact plugin to add a contact to the device. You can check out the sample in my github page
Since you are facing difficulties with plugins, i have added the plugin folder as well in the sample. You can copy the project, add android platform, build and test the same. Hope it helps
I had the same problem using this plugin. I think this is a version issue but the documentation has not been updated.
This is how I proceeded:
first import Contacts in your app.module.ts file
import { Contacts } from '#ionic-native/contacts';
...
...
providers: [
...
Contacts,
...
]
then import classes you want to use in your file
import { Contacts, Contact , ContactField, ContactName } from '#ionic-native/contacts';
...
constructor(private contacts: Contacts) {}
Now you can use you object
createContact(name, number){
let contact: Contact = this.contacts.create();
contact.name = new ContactName(null, '', name);
contact.phoneNumbers = [new ContactField('mobile', number,true),new ContactField('home', number+1,true)];
contact.save().then(
() => alert('Contact saved!'+ JSON.stringify(contact)),
(error: any) => alert('Error saving contact.'+error)
);
}
Here I create a contact with 2 phone numbers. Of course you can use the other functions find () and pickContact ().

Found not working imports: QtMultimedia is not installed

import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Dialogs 1.2
import QtMultimedia 5.6
import QtQuick.Layouts 1.3
Item {
width: 640
height: 360
Camera {
id: camera
imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceFlash
exposure {
exposureCompensation: -1.0
exposureMode: Camera.ExposurePortrait
}
flash.mode: Camera.FlashRedEyeReduction
imageCapture {
onImageCaptured: {
photoPreview.source = preview // Show the preview in an Image
}
}
}
VideoOutput {
source: camera
anchors.fill: parent
focus : visible // to receive focus and capture key events when visible
}
Image {
id: photoPreview
}
}
I just uinstalled Qt 5.5.1 and installed Qt 5.6 (but above is the new project created in Qt 5.6). I added
QT += multimedia
in my pro file. I use MSVC 2013 (as alway when using Qt), Windows 7. It builds program and when I click Run, it works, although it shows in Application Output: 3x failed to access to the graph builder. I could ignore it, but I am not able to access to Design mode ("Cannot open this QML document beacuse of an error in the QML file"). Could you help me to solve it?
Copying the missing module manually to
%QT_CREATOR_INSTALLATION%\bin\qml\ can solve your problem. This is
because Qt Creator, here in Design mode, only import modules from
%QT_CREATOR_INSTALLATION%\bin\qml\ folder.
After copying, you may or may not face another question. The module
that you copied may not work in the design mode. Because the module
must be well designed and tested before it can be used in the design
mode. In fact, the module must be marked as designersupported in
it's qmldir file.
QtMultimedia is not installed in the %QT_CREATOR_INSTALLATION%\bin\qml\ folder and not marked as designersupported. So, you can't use it in the Design mode.

Categories

Resources