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 ().
Related
I am a rookie and I was trying to learn about how to use Stimulus online and then suddenly
my console does not show output(in inspect element) when I use Stimulus in rails app
app/javascript/controllers/dropdown_controller.js
import { Controller } from "#hotwired/stimulus"
// Connects to data-controller="dropdown"
export default class extends Controller {
connect() {
console.log("Hello")
}
}
app/javascript/aplication.js
// Entry point for the build script in your package.json
import "#hotwired/turbo-rails"
import "./controllers"
app/views/orders/_form.html.erb
<div data-controller="dropdown">
<h3>Hello</h3>
</div>
(I didn't display the whole form because this is the main context in the form which is related to Stimulus) So what is the problem here? Why is it not showing output in the console(inspect element in chrome)
According to other Stackoverflow posts, we had to run rails assets:clobber in order to fix it but mine still does not work :(
Any Chance I am doing something dumb?
I have a blog run on Gatsby, and every time I push and deploy new blog posts I need to do a refresh on my page to see the new data.
I tried following the suggestions from this post and adding an onServiceWorkerUpdate function but that doesn't seem to have done anything.
Anyone have workarounds to this issue, and if so will there be a way to test locally? Changes already automatically update when I test in gatsby develop mode.
This is the entirety of my gatsby-browser.js file
export const onServiceWorkerUpdateReady = () => window.location.reload();
You need to install gatsby-plugin-offline first. Leaving your gatsby-config.js with something similar to:
{
plugins: [
{
resolve: `gatsby-plugin-manifest`,
options: {
...
}
},
'gatsby-plugin-offline'
]
}
Note: plugin's order matters in this case.
The plugin will register a service worker and will load it into the client.
Then, in your gatsby-browser.js file you can simply add:
export const onServiceWorkerUpdateReady = () => {
const answer = window.confirm(
`This application has been updated. ` +
`Reload to display the latest version?`
)
if (answer === true) window.location.reload()
}
Additionally, you may want to add the following hack (very common across the repositories):
export const onRouteUpdate = () => {
navigator.serviceWorker.register('/sw.js').then((reg) => {
reg.update();
});
};
Basically, it forces the registration of the service-worker across the site upon the onServiceWorkerUpdateReady refresh.
Check this interesting thread for further caveats and workarounds for some specific scenarios: https://github.com/gatsbyjs/gatsby/issues/9087#issuecomment-774680408
It will not work using Link provided by gatsby
import { Link as GatsbyLink } from 'gatsby';
<GatsbyLink to={to} {...props} />
It works using traditional a tag:
<a href={props.to} target="_blank">
{props.children}
</a>
I'm trying to create cypress test project which support page object model.
I have created a new folder 'pageobject' at ../integration and there I have implemented LoginPageAdminPortal.js file as a page object class.
Code is like below,
export class LoginPageAdminPortal
{
visitLoginPageAdminPortal()
{
cy.visit (cypress.env('ADMIN_PORTAL_LOGIN_URL'))
}
loginAdminPortal()
{
cy.get('input[name=usernameUserInput]').type(cypress.env('ADMIN_USER_NAME'))
cy. get('input[name=password]').type(cypress.env('ADMIN_USER_PASSWORD'))
cy.contains('Continue').click()
return this
}
}
Then I wrote a test script for user login and the test sript locate at integration folder.
import {LoginPageAdminPortal} from '/pageobject/'
describe('Admin portal login with username and password', () => {
it ('Visit to the admil poratl login page', () => {
const loginPage = new LoginPageAdminPortal()
loginPage.visitLoginPageAdminPortal()
})
})
But at the compilation time I'm getting error like,
Error: Cannot find module '../pageobject/' from ' /home/achini/projects/cloudtest/cypress/cypress-iam-ui-test/iam-cypress-ui-test/cypress/integration'
Do I have to configure the pageobject module some other file. Any idea to solve this and successfully implement cypress with page object model.
folder structure
reference :
https://www.youtube.com/watch?v=5ifXs65O36k
https://www.youtube.com/watch?v=hMiBundGmNA
Imports are relative to the test which is in the integration folder, so you want
import { LoginPageAdminPortal } from './pageobject/LoginPageAdminPortal';
Please check out these two repositories where I implemented an example of the PO pattern. In one repository, I did it with TypeScript, and in the other one, I did it with JavaScript.
https://github.com/antonyfuentes/cypress-typescript-page-objects
https://github.com/antonyfuentes/cypress-javascript-page-objects
I think a good practice is to keep the integration folder only with your tests files. You can move the pageobject folder under support and use
import LoginPageAdminPortal from '../../support/PageObjects/LoginPageAdminPortal'in order to access the file.
I am new to google calendar api and react so I'm sure there is something small I'm missing here. I cannot import the necessary google api libraries to call "gapi." I have try to import them like I would do from local libraries but still get the error "gapi is not defined". I need to use the "gapi" in my component so I don't think I can call and append the script to the body using the componentDidLoad.
// Libraries
import React, {Component} from 'react';
//...import other libraries
//import google libraries in order to use "gapi" and call "checkAuth"
import 'https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js';
import 'https://apis.google.com/js/client.js?onload=checkAuth';';
var CLIENT_ID = 'MY_CLIENT_ID_IS_HERE';
var SCOPES = ["https://www.googleapis.com/auth/calendar"];
class NewCalendar extends Component {
constructor(props) {
super(props);
this.checkAuth = this.checkAuth.bind(this);
}
checkAuth() {
console.log('checkAuth running...')
gapi.auth.authorize( //ISSUE
^issue with the last line
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true
}, this.handleAuthResult);
}
...
}
export default NewCalendar;
Does anyone know how to resolve this issue?
Thanks a million.
I struggled with similiar issues. Thats how I solved it. In this case you Need to put the window. scope infront. But hopfeully you found a solution until now ;) Want to share this anyway, maybe it's not the best solution but works for me for the Moment.
componentDidMount() {
this.loadApi();
}
loadApi() {
const script = document.createElement("script");
script.src = "https://apis.google.com/js/api.js";
document.body.appendChild(script);
script.onload = () => {
window.gapi.load('client:auth2', this.checkAuth.bind(this));
}
}
bye
I am pretty new to React and JSX but it seems that you might have ideas to answer your problems here:
GAPI is not defined - ReactJS - Google Sheets
https://github.com/anthonyjgrove/react-google-login/blob/master/src/index.js#L33
It seems that import only works for local files, and that you will need to to async load of the gapi (https://jsx.github.io/doc/importref.html)
Hope that helps
Place your https://apis.google.com/js/api.js inside a script tag inside of your index.html file, below your meta tag. That should be it.
Then in the browser, refresh the page and in your JavaScript console, you should be able to write out gapi and you should be able to see an object like so: {load: f}.
That object would be the Google API that is available on the window scope of your browser.
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