How to add Jitsi Meet to Vuejs - javascript

I have loaded the jitsi meet script in the body of my public.html, and i have a component as follows:
<template>
<div class="container">
<div id="meet"></div>
</div>
</template>
<script>
export default {
name: "ServiceMeet",
mounted() {
const domain = "meet.jit.si";
const options = {
roomName: "PickAnAppropriateMeetingNameHere",
width: 700,
height: 700,
parentNode: document.querySelector("#meet"),
};
const api = new JitsiMeetExternalAPI(domain, options);
console.log(api.getVideoQuality());
},
};
</script>
When I try to run I get an error saying 18:21 error 'JitsiMeetExternalAPI' is not defined no-undef, however in the background i can see that the meet is working fine, so I do I fix the error or dismiss it.

You could disable the linting error, but I would recommend specifying it as a global variable instead.
.eslintrc.js
module.exports = {
globals: {
JitsiMeetExternalAPI: true
}
}

It should work if you prefix the global with window:
const api = new window.JitsiMeetExternalAPI(domain, options);

Related

Vue3 Display PDF Document

I can grab images and display them in a browser using them as a bytearray without any problem. In Normal C# I was also able to do this with PDFs very easily by inserting this bytearray as an but now in Vue3 I am having troubles doing this same thing I've done in the past. What is a simple way to display a PDF document In browser with Vuejs?
This is how I've done in in the past,
I am open to suggestions and a better way to do this.
This will be hosted and be shown on a big screen TV so the department can view the document and it will flash to other ones as well.
<div v-if="byteArrayPDF" class="content">
<object data="byteArrayPDF" type="application/pdf" style="height:700px;width:1100px;"></object>
</div>
</div>
</template>
<script lang="js">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
loading: false,
byteArrayPDF: null
};
},
created() {
this.fetchByteArray();
},
methods: {
fetchByteArray() {
this.byteArrayPDF = true;
this.loading = null;
fetch('https://localhost:5001/api/Doc/Virtual-Visual-Service-2020.pdf')
.then(response => response.json())
.then(bytespdf => {
this.byteArrayPDF = "data:application/pdf;base64," + bytespdf;
this.loading = false;
return;
})
.catch(console.log("Error PDF View"));
}
From what you said in your question, I think you want to load a pdf file in for example a "vue component". If that is right, you can use a code like the code below:
<template>
<div v-if="byteArrayPDF">
<iframe :src="srcData" width="100%" height="500px">
</iframe>
</div>
<div v-else>
loading...
</div>
</template>
<script>
export default {
name: "CompoPdf",
data() {
return {
srcData: null,
byteArrayPDF: false,
}
},
created() {
this.fetchByteArray();
},
methods: {
fetchByteArray: async function () {
// to see the "loading..." effect, I intentionally add a "setTimeout" code. that loads the pdf after "3s". You can remove it in your real app.
await new Promise(resolve => setTimeout(resolve, 3000));
fetch('https://www.antennahouse.com/hubfs/xsl-fo-sample/pdf/basic-link-1.pdf')
.then(response => {
console.log(response);
// for this case "response.url" is what we need, but if you fetch data for example from a database ... you may need "response.json()" or other codes;
this.srcData = response.url;
this.byteArrayPDF = true;
})
}
}
}
</script>
<style scoped>
</style>
I also suggest that you read more about fetch API and CORS if you are not familiar with that topics, to better manage your request to the url you want.

Using Google One Tap in Angular

I'd like to use Google One Tap in my Angular 11 app. Following the documentation I added <script async defer src="https://accounts.google.com/gsi/client"></script> to my html and then used the following code in my app.component.html:
<div id="g_id_onload"
data-client_id="MY_GOOGLE_CLIENT_ID"
data-callback="handleCredentialResponse",
data-cancel_on_tap_outside="false">
</div>
The popup works fine, though I can't seem to log in. If I create a function handleCredentialResponse in app.component.ts, I get the following error: [GSI_LOGGER]: The value of 'callback' is not a function. Configuration ignored.
If I instead try to use the JavaScript API, Typescript throws the following error: Property 'accounts' does not exist on type 'typeof google'
What should I do to be able to using Google One Tap in Angular?
I had a similar problem when I used the HTML API approach, so I ended up using the JavaScript API instead.
Here's what I did:
First, make sure to install the #types/google-one-tap package.
As you mentioned, I'm also importing the script in my index.html file, like so:
<body>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<app-root></app-root>
</body>
Now, moving on to your main component which in my case is app.component.ts, import the following first:
import { CredentialResponse, PromptMomentNotification } from 'google-one-tap';
Then, you can add this on the ngOnInit(). Make sure to read the documentation to get more details on the onGoogleLibraryLoad event:
// #ts-ignore
window.onGoogleLibraryLoad = () => {
console.log('Google\'s One-tap sign in script loaded!');
// #ts-ignore
google.accounts.id.initialize({
// Ref: https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration
client_id: 'XXXXXXXX',
callback: this.handleCredentialResponse.bind(this), // Whatever function you want to trigger...
auto_select: true,
cancel_on_tap_outside: false
});
// OPTIONAL: In my case I want to redirect the user to an specific path.
// #ts-ignore
google.accounts.id.prompt((notification: PromptMomentNotification) => {
console.log('Google prompt event triggered...');
if (notification.getDismissedReason() === 'credential_returned') {
this.ngZone.run(() => {
this.router.navigate(['myapp/somewhere'], { replaceUrl: true });
console.log('Welcome back!');
});
}
});
};
Then, the handleCredentialResponse function is where you handle the actual response with the user's credential. In my case, I wanted to decode it first. Check this out to get more details on how the credential looks once it has been decoded: https://developers.google.com/identity/gsi/web/reference/js-reference#credential
handleCredentialResponse(response: CredentialResponse) {
// Decoding JWT token...
let decodedToken: any | null = null;
try {
decodedToken = JSON.parse(atob(response?.credential.split('.')[1]));
} catch (e) {
console.error('Error while trying to decode token', e);
}
console.log('decodedToken', decodedToken);
}
I too had the same problem in adding the function to the angular component.
Then i found a solution by adding JS function in appComponent like this:
(window as any).handleCredentialResponse = (response) => {
/* your code here for handling response.credential */
}
Hope this help!
set the div in template to be rendered in ngOnInit
`<div id="loginBtn" > </div>`
dynamically inject script tag in your login.ts as follows
constructor(private _renderer2: Renderer2, #Inject(DOCUMENT) private _document: Document){}
ngAfterViewInit() {
const script1 = this._renderer2.createElement('script');
script1.src = `https://accounts.google.com/gsi/client`;
script1.async = `true`;
script1.defer = `true`;
this._renderer2.appendChild(this._document.body, script1);
}
ngOnInit(): void {
// #ts-ignore
window.onGoogleLibraryLoad = () => {
// #ts-ignore
google.accounts.id.initialize({
client_id: '335422918527-fd2d9vpim8fpvbcgbv19aiv98hjmo7c5.apps.googleusercontent.com',
callback: this.googleResponse.bind(this),
auto_select: false,
cancel_on_tap_outside: true,
})
// #ts-ignore
google.accounts!.id.renderButton( document!.getElementById('loginBtn')!, { theme: 'outline', size: 'large', width: 200 } )
// #ts-ignore
google.accounts.id.prompt();
}
}
async googleResponse(response: google.CredentialResponse) {
// your logic goes here
}
Google One Tap js library tries to find callback in the global scope and can't find it, because your callback function is scoped somewhere inside of your app, so you can attach your callback to window, like window.callback = function(data) {...}.
Also, since you are attaching it to window, it's better to give the function a less generic name.

VUE JS Dynamic background image after axios request

I'm trying to display a background image that it's path needs to be loaded through an API.
The plan is: From a main grid of links, click one and display a background image according to the one clicked.
As of now I am using axios to query my API which sends the data I need. I have the following script part on my component.
<script>
import axios from 'axios'
const lhost = require("#/config/global").host;
let championData;
export default {
name: 'IndividualChampion',
props: {
},
data: () => ({
champions: [],
verPersonagem: mdiMovieOpen,
}),
computed: {
},
created: async function() {
try {
let champion = this.$route.fullPath.split('/')[2];
let response = await axios.get(lhost + "/champion/" + champion + '/full');
championData = response.data
console.log(championData)
let background = '#/assets' + championData['skins']['0']['splash'].replace('.png','.jpg')
}
catch (e) {
return e;
}
},
methods: {
}
}
</script>
And this is my HTML
<template>
<div :style="{ backgroundImage: `url(${require(background)})` }">
</div>
</template>
I have searched but can't seem to find a solution in which the background image is loaded and, when loaded, is presented.
Can someone help?
Judging from your use of '#/assets', you seem to be using webpack with a resolve alias. The expression require(background) is not enough for webpack to determine what files it needs to add to your bundle.
You can help Webpack by specifying the directory that you want to load your file from. All you have to do is take out '#/assets/' from the background variable and use it directly in the require call so that Webpack can see it.
<template>
<div v-if="background" :style="{ backgroundImage: `url(${require('#/assets/' + background)})` }">
</div>
</template>
<script>
import axios from 'axios'
const lhost = require("#/config/global").host;
let championData;
export default {
name: 'IndividualChampion',
props: {
},
data: () => ({
champions: [],
verPersonagem: mdiMovieOpen,
background: ''
}),
computed: {
},
created: async function() {
try {
let champion = this.$route.fullPath.split('/')[2];
let response = await axios.get(lhost + "/champion/" + champion + '/full');
championData = response.data
console.log(championData)
this.background = championData['skins']['0']['loading'].replace('.png','.jpg')
}
catch (e) {
return e;
}
},
methods: {
}
}
</script>
It will bundle every possible file inside the directory, though.
You can read more about it here: https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import

VUE.JS - How to use a class that is outside of vue.js in the javascript file of vue.js?

I'm using vue.js to create a webpage, and I'm trying to use a class (Authenticator) that is outside of my two files (Login.html and Login.js) that are using vue.js. But I can't seem to manage to import that class (Authenticator) in my Login.js file to use it's function...
Is there a way to do that? Here is my code:
Login.html
<!DOCTYPE html>
<html>
<head>
</head>
<body class="background">
<div class="border">
<div id="app">
[...]
</div> <!-- End of app -->
</div> <!-- End of border -->
<script src="./vue.js"></script>
<script src="./Login.js"></script>
<script src="../controller/Authenticator.js"></script>
</body>
</html>
Login.js
var app = new Vue({
el: '#app',
data: {
username: null,
password: null,
activeUsers: []
},
methods: {
verifyLogin: function () {
// Verify if fields have been filled
if (null === this.username || null === this.password) {
window.alert("Error, please fill out the form correctly!");
} else {
// If fields are filled, verify the authentication
var authenticator = new Authenticator(this.username);
var authenticated = authenticator.authenticateUser(this.username, this.password);
[...]
} else if (null === authenticated) {
// Error, if authentication failed
window.alert("Wrong password, please try again!")
}
}
}
}
});
Authenticator.js
const MongoClient = require('mongodb').MongoClient;
var url = "mongodb://192.168.99.100:27017/UserDB";
const bcrypt = require('bcrypt'); // Hash algorithm
const saltRounds = 10;
export default class Authenticator {
constructor(iNewUserName) {
this.mActiveUserNames.push(iNewUserName);
}
async authenticateUser(iUserName, iPassword) {
[...]
}
}
I get the error "Uncaught SyntaxError: Unexpected token 'export'" on the webpage console. Also, I tried to change the method of exporting by doing:
module.exports = Authenticator;
But then I get the error "Uncaught ReferenceError: require is not defined at Authenticator.js:2" from the webpage console.
Can someone help me please, I looked everywhere online, and I cannot find the solution?
Thank you.

Vue.js import images

So I am making an app with a control panel and i want to be able to change a few images inside the app dynamically and my problem is, it just won't work
This is the div I am trying to change
<div class="bg-image bg-parallax overlay" :style="`background-image:url(${bg1url})`"></div>
this is the script part of the Home.vue file
<script>
import axios from 'axios';
export default {
name: 'Home', // this is the name of the component
data () {
return{
page_data: {},
bg1url: null,
};
},
created() {
axios.get("http://localhost:5001/api/v1/pages")
.then((result) => {this.page_data = result.data.page_data});
this.bg1url = require('#/assets/img/' + this.page_data.background1);
alert(page_data.background1);
},
};
</script>
I have tried most of the suggestions on stack overflow but nothing seems to work.
I use the default webpack configurations and generated structure
Note: the parts with axios fetching from the backend work correctly. The only problem is adding the image to the style.
I think could be because you are setting the value for bg1url outsite of promise (calback function of axios), and so this make the code sync and not async
so please try to update, use this instead
created() {
axios.get("http://localhost:5001/api/v1/pages").then(result => {
this.page_data = result.data.page_data
this.bg1url = require('#/assets/img/' + this.page_data.background1);
});
},

Categories

Resources