Reputation: 410
I need to use WebShareAPI in my Ionic application.
Here is my code as suggested in Introducing the Web Share API
if (window.navigator && window.navigator.share) {
window.navigator.share({
title: 'title',
text: 'description',
url: 'https://soch.in//',
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
} else {
alert('share not supported');
}
However, Typescript compilation fails with the following error:
[11:31:11] typescript: src/pages/channel_home/channel_home.ts, line: 89
Property 'share' does not exist on type 'Navigator'.
There is a likely reason explained here DOM lib: add support for navigator.share
However, I would like to know some workaround to make WebShareApi work in my Ionic app in particular, and in any Angular or Typescript app in general.
Upvotes: 31
Views: 33511
Reputation: 18381
Based on this answer,
you can try to define a variable of type any
and assign to it your value of Type Navigator. The issue is related to TypeScript typings.
const newVariable: any = window.navigator;
if (newVariable?.share) {
newVariable.share({
title: 'title',
text: 'description',
url: 'https://soch.in//',
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
} else {
alert('Share is not supported');
}
Another option would be to extend the interface Navigator as it is suggested in the link I posted above.
Upvotes: 37
Reputation: 77
Don't use navigator.share/caches/serial and many more directly, this will lead you to an error on the HTTP connection. Verify it exists before the direct call to the property.
if ('share' in navigator) {
//Do stuff
} else {
alert('Share API not supported');
}
Upvotes: 1
Reputation: 1689
This is fixed in Typescript's latest versions (I am not exactly sure which one, but I guess since v4.3-beta
version). Check this thread for details - https://github.com/microsoft/TypeScript/issues/18642
Also, The example shared below, once updated to the latest version will not work, as it conflicts with Typescript's own typings. Thus, do not apply those changes or keep the type similar to the parent:
// global.d.ts
interface Navigator extends Navigator {
share: (options?: ShareData) => Promise<void>;
}
share
property has been removed from being optional, as per the specs, details implemented in Firefox, changes in Firefox
We can do this the Typescript
way:
Firstly we need to define custom typings for our project. So, we need to define a /typings
or /@types
folder in your root directory.
.
└── typings
Once that is done, you need to update your tsconfig.json
file to point the new custom typings folder to this one.
{
"compilerOptions": {
...
"typeRoots": [
"./node_modules/@types",
"./typings"
]
},
"include": [
...
"typings",
"**/*.ts",
"**/*.tsx"
]
...
}
This will allow Typescript to look for custom types in /typings
folder.
References for above:
Once the above is done, we need to create a Global .d.ts
file that Typescript will look into for detecting custom types. So, in your /typings
folder create a new file named global.d.ts
.
// global.d.ts
interface Navigator extends Navigator {
share?: (options: any) => Promise<void>;
}
What we are doing, is overriding the default Navigator
with some extra properties to support.
Once you declare the above interface, Typescript will allow you to use navigator.share
, but you need to put it inside a conditional block, as share
is optional property, it might or might not be present in a Browser.
Hope this helps!!
Upvotes: 8
Reputation: 3070
If you keep getting the error, despite following the advices on this site, make sure that your page is server via https
. The share functionality is not available on plain http. The following snipped worked for me.
const nav: any = window.navigator;
nav.share({ title: "Shared via my https page", url: "relativeLink" })
Upvotes: 0
Reputation: 1730
in my case: in Angular, on a module I use:
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
and typescript show the error MozGetUserMedia is not a property.
I fixed using:
declare const navigator: any;
Maybe the same approach will works for you:
Upvotes: 3
Reputation: 1683
For anyone looking for a proper answer, just add this to your global.d.ts
file:
type ShareData = {
title? : string;
text? : string;
url? : string;
};
interface Navigator
{
share? : (data? : ShareData) => Promise<void>;
}
This properly reflects the level 1 API.
Upvotes: 14
Reputation: 1243
This also works and we don't need to create a newVariable.
if (window.navigator && window.navigator.share) {
window.navigator['share']({
title: 'title',
text: 'description',
url: 'https://soch.in//',
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
} else {
alert('share not supported');
}
Upvotes: 5
Reputation: 31
This worked for me
let newVariable = (window.navigator as any)
if(newVariable.share){
newVariable.share({
title: 'title',
text: 'description',
url: 'https://soch.in//',
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
} else {
alert('share not supported');
}
Upvotes: 3