I have a project in Vue3 and want to implement a real time API or a web socket. So I attempted to use pusher using Vue third part libraries which are pusher-vue and vue-pusher. Using pusher-vue I am getting the error: Uncaught TypeError: e.prototype is undefined. Using vue-pusher I am getting the error: Uncaught TypeError: Vue.prototype is undefined. The following are the libraries' configurations:
PUSHER VUE
Component.vue
export default{
channels: {
applications_channel: {
subscribeOnMount: true,
subscribed(){
console.log("Some text")
},
bind:{
add_application_event(data){
console.log(data)
}
}
}
}
}
main.js
createApp(App)
.use(PusherVue, {
app_key: "MY_KEY",
cluster: 'MY_CLUSTER',
debug: true,
debugLevel: "all"
})
.mount("#app")
VUE PUSHER
Component.vue
export default{
read(){
var channel = this.$pusher.subscribe('applications-channel')
channel.bind('add-application-event', ({ log }) => {
console.log(log);
})
}
}
main.js
createApp(App)
.use(require("vue-pusher"), {
api_key: "MY_KEY",
options: {
cluster: 'MY_CLUSTER',
ecrypted: true,
}
})
.mount("#app")
May you please help with how can I configure this on Vue3 or recommend any beginner friendly alternatives to achieve the same functionality on Vue3.
Both pusher-vue and vue-pusher were built for Vue 2, so you need to use the Vue 3 migration build to make the library work in your project.
To setup your Vue CLI scaffolded project:
Install the Vue compatibility build and SFC compiler that matches your Vue build version (i.e., install #vue/compat#^3.1.0 and #vue/compiler-sfc#^3.1.0 if you have vue#^3.1.0 in package.json):
npm i -S #vue/compat#^3.1.0
npm i -S #vue/compiler-sfc#^3.1.0
Configure Webpack to alias vue to the #vue/compat build, and set vue-loader's compatibility mode to Vue 2:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('vue', '#vue/compat')
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
return {
...options,
compilerOptions: {
compatConfig: {
MODE: 2
}
}
}
})
}
}
demo: vue-pusher in Vue 3 w/migration build
However, vue-pusher 1.1.0 seems to only expose a new instance of Pusher (from pusher-js) as this.$pusher on the Vue instance. That code could easily be migrated to Vue 3 as a plugin:
// plugins/pusher.js
export default (app, { apiKey, ...options }) => {
const Pusher = require('pusher-js')
app.config.globalProperties.$pusher = new Pusher(apiKey, options)
}
// main.js
const { createApp } = require('vue')
import App from './App.vue'
import PusherPlugin from './plugins/pusher'
createApp(App)
.use(PusherPlugin, { apiKey: 'YOUR_API_KEY', cluster: 'YOUR_CLUSTER' })
.mount('#app')
demo: pusher-js in Vue 3
I have a Vue.js app which i'm currently using workbox to cache so it works offline. However, videos don't seem to work in Safari.
I've researched and all signs point to this:
https://developers.google.com/web/tools/workbox/guides/advanced-recipes#cached-av
but it doesn't seem to work for me.
Here's my code as it stands:
Webpack
configureWebpack: {
plugins: [
new InjectManifest({
swSrc: './src/sw.js',
swDest: "sw.js",
maximumFileSizeToCacheInBytes: 5000000000
})
]}
sw.js (service worker)
import { skipWaiting, clientsClaim } from "workbox-core";
import { precacheAndRoute } from "workbox-precaching";
import { registerRoute } from "workbox-routing";
import { CacheFirst } from "workbox-strategies";
import { CacheableResponsePlugin } from "workbox-cacheable-response";
import { RangeRequestsPlugin } from "workbox-range-requests";
registerRoute(
({ url }) => url.pathname.endsWith(".mp4"),
new CacheFirst({
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
new RangeRequestsPlugin()
]
})
);
skipWaiting();
clientsClaim();
precacheAndRoute(self.__WB_MANIFEST);
This is likely because your .mp4 files have a __WB_MANIFEST URL query parameter appended to them in the cache, since they need to be versioned by Workbox's precaching logic.
A quick solution would be to set matchOptions when constructing the strategy:
new CacheFirst({
matchOptions: { ignoreSearch: true },
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
new RangeRequestsPlugin()
]
})
I realised as I was precaching I had to specify what cache to use in the CacheFirst object, as the default is set to the runtime cache. To do this, I imported cacheNames from workbox-core
import { skipWaiting, clientsClaim, cacheNames } from "workbox-core";
Then I set the precache name
const precacheCacheName = cacheNames.precache;
Then in when setting up the CacheFirst object I specified the name as such:
new CacheFirst({
cacheName: precacheCacheName,
Here's the complete code:
import { skipWaiting, clientsClaim, cacheNames } from "workbox-core";
import { precacheAndRoute } from "workbox-precaching";
import { registerRoute } from "workbox-routing";
import { CacheFirst } from "workbox-strategies";
import { CacheableResponsePlugin } from "workbox-cacheable-response";
import { RangeRequestsPlugin } from "workbox-range-requests";
const precacheCacheName = cacheNames.precache;
registerRoute(
({ url }) => url.pathname.endsWith(".mp4"),
new CacheFirst({
cacheName: precacheCacheName,
matchOptions: { ignoreSearch: true },
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
new RangeRequestsPlugin()
]
})
);
skipWaiting();
clientsClaim();
precacheAndRoute(self.__WB_MANIFEST);
I am trying to use bugsnagClient and its notify method in plugins/axios.js I have this code in plugins/bugsnag.js
import Vue from "vue"
import bugsnag from "#bugsnag/js"
import bugsnagVue from "#bugsnag/plugin-vue"
// const bugsnagClient = bugsnag(`${process.env.BUGSNAG_API_KEY}`)
var bugsnagClient = bugsnag({
apiKey: "",
notifyReleaseStages: ["production"]
})
bugsnagClient.use(bugsnagVue, Vue)
I want to attach a method to app or context as
export default ({ app }, inject) => {
function bugsnagNotify(error) {
return bugsnagClient.notify(new Error(error))
}
// Set the function directly on the context.app object
app.bugsnagNotify = bugsnagNotify
}
And I want to use it in plugins/axios.js
export default function({ store, app }) {
if (store.getters.token) {
console.log(app.bugsnagNotify("ss"))
app.$axios.setToken(store.getters.token, "Bearer")
} else {
//app.$bugsnag.notify(new Error("Bearer tooken is missing in Axios request."))
}
}
In this file, when I do console.log for just app
I can see bugsnagNotify: ƒ bugsnagNotify(error)
but when I call app.bugsnagNotify("error") I only get error such as VM73165:37 TypeError: app.bugsnagNotify is not a function
I have also tried this in plugins/bugsnag.js
export default (ctx, inject) => {
inject('bugsnag', bugsnagClient)
}
I only get an error as
app.$bugsnag.notify(new Error("Bearer tooken is missing in Axios request."))
If you are injecting into context inside one plugin and want to use that function inside another, you need to make sure that the plugin in which you are injecting comes first inside nuxt.config.js
...
plugins: [
'~/plugins/bugsnag.js',
'~/plugins/axios.js'
],
...
I'm trying to use the aurelia-i18n plugin in with the latest typescript webpack skeleton.
So I have installed the needed npm packages
npm install aurelia-i18n --save
npm install i18next-xhr-backend --save
npm install i18next-browser-languagedetector --save
Then I have changed my main.ts
import { Aurelia } from 'aurelia-framework';
import { PLATFORM } from 'aurelia-pal';
import XHR from 'i18next-xhr-backend';
import LngDetector from 'i18next-browser-languagedetector';
export async function configure(aurelia: Aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.plugin(PLATFORM.moduleName('aurelia-i18n'), (instance) => {
// register i18n plugins
instance.i18next
.use(XHR)
.use(LngDetector);
// adapt options to your needs (see http://i18next.com/docs/options/)
// make sure to return the promise of the setup method, in order to guarantee proper loading
return instance.setup({
backend: { // <-- configure backend settings
loadPath: './Locale/{{lng}}/{{ns}}.json', // <-- XHR settings for where to get the files from
},
detection: {
order: ['localStorage', 'cookie', 'navigator'],
lookupCookie: 'i18next',
lookupLocalStorage: 'i18nextLng',
caches: ['localStorage', 'cookie']
},
attributes: ['t', 'i18n'],
fallbackLng: 'en',
load: 'languageOnly',
debug: false,
ns: ['translation',
'StammAlbum',
'StammCategory',
'StammCategoryValue',
'StammPictureAdmin',
'StammPictureUpload',
'StammVideoUpload',
'StammVideoAdmin',
'VideoKonverter',
'Router',
'Datamappings',
'Toasts',
'Alerts',
'Controls',
'Metadata',
'Dialogs',
'AuthRegister',
'SecurityQuestions',
'Countries',
'Validation',
'AuthConfirmAccount',
'AuthLogin',
'AuthForgotPassword',
'AuthAdminAccount',
'AuthNewPassword',
'Messages'],
defaultNS: 'translation'
});
});
await aurelia.start();
await aurelia.setRoot(PLATFORM.moduleName('FamilieLaissApp'));
}
The webpack bundler shows no errors. But in the browser console I can see a 404 Error for every Translation-File.
So I have tried the solution that is documented on the aurelia hub for using the built in backend and changed the main.ts
import { Aurelia } from 'aurelia-framework';
import { PLATFORM } from 'aurelia-pal';
import {I18N, Backend} from 'aurelia-i18n';
import LngDetector from 'i18next-browser-languagedetector';
export async function configure(aurelia: Aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.plugin(PLATFORM.moduleName('aurelia-i18n'), (instance) => {
// register i18n plugins
instance.i18next
.use(Backend.with(aurelia.loader))
.use(LngDetector);
// adapt options to your needs (see http://i18next.com/docs/options/)
// make sure to return the promise of the setup method, in order to guarantee proper loading
return instance.setup({
backend: { // <-- configure backend settings
loadPath: './Locale/{{lng}}/{{ns}}.json', // <-- XHR settings for where to get the files from
},
detection: {
order: ['localStorage', 'cookie', 'navigator'],
lookupCookie: 'i18next',
lookupLocalStorage: 'i18nextLng',
caches: ['localStorage', 'cookie']
},
attributes: ['t', 'i18n'],
fallbackLng: 'en',
load: 'languageOnly',
debug: false,
ns: ['translation',
'StammAlbum',
'StammCategory',
'StammCategoryValue',
'StammPictureAdmin',
'StammPictureUpload',
'StammVideoUpload',
'StammVideoAdmin',
'VideoKonverter',
'Router',
'Datamappings',
'Toasts',
'Alerts',
'Controls',
'Metadata',
'Dialogs',
'AuthRegister',
'SecurityQuestions',
'Countries',
'Validation',
'AuthConfirmAccount',
'AuthLogin',
'AuthForgotPassword',
'AuthAdminAccount',
'AuthNewPassword',
'Messages'],
defaultNS: 'translation'
});
});
await aurelia.start();
await aurelia.setRoot(PLATFORM.moduleName('FamilieLaissApp'));
}
But also no luck with this solution. The 404 Errors are gone but the localized strings are not shown in my application. I can only see the Localization.Identifiers not the localized text, and the browser shows no error in the console output.
So what I have to do to get this thing to work?
Here is my working config. I don't use typescript, but your problem is related to the bundling of locale files with webpack
var Promise = require('bluebird'); // Promise polyfill for IE11
Promise.config({
// Enable warnings
warnings: false,
// Enable long stack traces
longStackTraces: true,
// Enable cancellation
cancellation: false,
// Enable monitoring
monitoring: false
});
import 'intl';
import 'intl/locale-data/jsonp/en';
import 'intl/locale-data/jsonp/de';
import {bootstrap} from 'aurelia-bootstrapper-webpack';
import '../theme/assets/css/jquery-ui.css';
//import '-!style!css!../theme/assets/css/jquery-ui.css';
// note! import bootstrap styles after ace
import '../theme/assets/css/ace.css';
import '../theme/assets/css/bootstrap.css';
import '../styles/main.less';
import 'jquery-ui/jquery-ui';
// just js from bootstrap
import 'bootstrap-webpack/bootstrap-scripts!bootstrap-webpack/bootstrap.config.js';
// always import ace-theme after jquery-ui and bootsrap
import 'ace-theme/ace';
import 'ace-theme/ace-elements';
import 'font-awesome-webpack';
import XHR from 'i18next-xhr-backend';
function loadLocales(url, options, callback, data) {
try {
let waitForLocale = require('bundle!json!../locale/' + url + '.json');
waitForLocale((locale) => {
callback(locale, {status: '200'});
})
} catch (e) {
callback(null, {status: '404'});
}
}
bootstrap(function (aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.plugin('aurelia-i18n', (instance) => {
// register backend plugin
instance.i18next.use(XHR);
// adapt options to your needs (see http://i18next.com/docs/options/)
return instance.setup({
backend: { // <-- configure backend settings
//loadPath: '/locale/{{lng}}/{{ns}}.json' // <-- XHR settings for where to get the files from
loadPath: '{{lng}}/{{ns}}',
parse: (data) => data,
ajax: loadLocales
},
lng: 'de',
attributes: ['t', 'i18n'],
fallbackLng: 'en',
debug: false,
//debug: true,
//compatibilityJSON: 'v1',
ns: ['translation', 'nav', 'secuident', 'validation']
});
})
.plugin('aurelia-validation')
.plugin('aurelia-dialog', config => {
config.useDefaults();
config.settings.startingZIndex = 5000;
});
aurelia.start().then(() => aurelia.setRoot('app-webpack', document.body));
});
I set up Ionic Cloud Service and went through the initial process of authorizing a user.
import {Component} from '#angular/core';
import {NavController} from 'ionic-angular';
import {Auth, User, UserDetails, IDetailedError} from '#ionic/cloud-angular';
#Component({
templateUrl: 'build/pages/signup/signup.html'
})
export class SignupPage {
constructor(public auth: Auth, public user: User){
let details: UserDetails = {'email': 'hi#ionic.io', 'password': 'puppies123'};
this.auth.signup(details).then(() => {
// `this.user` is now registered
}, (err: IDetailedError<string[]>) => {
for (let e of err.details) {
if (e === 'conflict_email') {
alert('Email already exists.');
} else {
// handle other errors
}
}
});
}
}
For some reason I am getting this error:ORIGINAL EXCEPTION: No provider for Auth!
ORIGINAL STACKTRACE:
Error: DI Exception
Everything is setup to a tee like the ionic cloud docs suggest : https://docs.ionic.io/services/auth/#setup
I've looked everywhere for this answer
In the setup instructions it talks about how to add the ionic cloud NgModule to your module's imports:
https://docs.ionic.io/setup.html
import { CloudSettings, CloudModule } from '#ionic/cloud-angular';
const cloudSettings: CloudSettings = {
'core': {
'app_id': 'APP_ID'
}
};
#NgModule({
declarations: [ ... ],
imports: [
IonicModule.forRoot(MyApp),
CloudModule.forRoot(cloudSettings)
],
bootstrap: [IonicApp],
entryComponents: [ ... ],
providers: [ ... ]
})
export class AppModule {}
I had missed these steps. Making this change fixed the problem.
Try this
#Component({
templateUrl: 'build/pages/signup/signup.html',
providers: [Auth]
})
Not sure if it works because the ionic docs don't say anything about this, but it seems logical looking at your Error
Passing Auth in providers, starts to show that error in console:
Cannot read property 'config' of undefined