Nuxt.js - Implementing a component using Plugin - plugins

I would like to implement a custom Toaster component into my NuxtJs application by this method this.$toast.show({}) What is the best way of approaching this? Sadly I can't find any documentation on this.

Sorry, I arrive one year late...
I had the same proplem. Here is my code:
The index of my plugin (index.js ; Nofification.vue is a classical Vue component):
import Notifications from './Notifications.vue'
const NotificationStore = {
state: [], // here the notifications will be added
settings: {
overlap: false,
horizontalAlign: 'center',
type: 'info',
timeout: 5000,
...
},
setOptions(options) {
this.settings = Object.assign(this.settings, options)
},
removeNotification(timestamp) {
...
},
addNotification(notification) {
...
},
notify(notification) {
...
},
}
const NotificationsPlugin = {
install(Vue, options) {
const app = new Vue({
data: {
notificationStore: NotificationStore,
},
methods: {
notify(notification) {
this.notificationStore.notify(notification)
},
},
})
Vue.prototype.$notify = app.notify
Vue.notify = app.notify
Vue.prototype.$notifications = app.notificationStore
Vue.component('Notifications', Notifications)
if (options) {
NotificationStore.setOptions(options)
}
},
}
export default NotificationsPlugin
Here I call my plugin and inject it in Nuxt:
import Notifications from '~/components/NotificationPlugin'
Vue.use(Notifications)
export default (context, inject) => {
inject('notify', Vue.notify)
}
In my case, I use it in another plugin (nuxtjs axios).
import NOTIFICATIONS from '~/constants/notifications'
export default function ({ error, $axios, app }) {
// Using few axios helpers (https://axios.nuxtjs.org/helpers):
$axios.onError((axiosError) => {
// eslint-disable-next-line no-console
console.log('Axios: An error occured! ', axiosError, axiosError.response)
if (process.server) {
...
} else {
app.$notify({
message: 'Mon message',
timeout: NOTIFICATIONS.DEFAULT_TIMEOUT,
icon: 'tim-icons icon-spaceship',
horizontalAlign: NOTIFICATIONS.DEFAULT_ALIGN_HORIZONTAL,
verticalAlign: NOTIFICATIONS.DEFAULT_ALIGN_VERTICAL,
type: 'success',
})
console.log('PRINT ERROR')
return Promise.resolve(true)
}
})
}
As I injected it, I think I could have done export default function ({ error, $axios, app, $notify }) { and directly use $notify (and not the app.$notify).
If you want a better understanding, feel free to consult #nuxtjs/toast which works the same way:
https://github.com/nuxt-community/community-modules/blob/master/packages/toast/plugin.js
And the matching Vue component:
https://github.com/shakee93/vue-toasted/blob/master/src/index.js
Good luck, this is not easy stuff. I'll try to add something easier to understand in the docs!

you can find in this package https://www.npmjs.com/package/vue-toasted
installation
npm install vue-toasted --save
make a file as name toast.js in plugin folder
toast.js
import Vue from 'vue';
import Toasted from 'vue-toasted';
Vue.use(Toasted)
add this plugin to nuxt.config.js
plugins: [
{ src: '~/plugins/toast', ssr: false },
],
now you able to use in your methods like this
this.$toasted.show('hello i am your toast')
hope this helps

Related

Why does my redirects() in NextJS not work?

what am I doing wrong? I'm building an accessible website with NextJS and want to redirect to fitting pages to the plain-language-counterpart. But since they are a different kind of language, their URLs are different, too.
My routes are built like this:
Standard language = my-website.com/about
Plain language = my-website.com/plain-language/about
And I have a switch where I can just change the /plain-language/ part
Now I have these routes:
my-website.com/accessible-webdesign
my-website.com/plain-language/for-disabled-persons
And if I click the switch on the first one, it will link me to my-website.com/plain-language/accessible-webdesign, which doesn't exist! So I used redirects() and also restarted my server to fix this, but it doesn't work. It doesn't redirect and I get a 404 just as before.
Can you check my code and tell me, what I should change to make it work?
Thank you!
This is my next.config.js:
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
/** #type {import('next').NextConfig} */
const path = require('path');
const withPWA = require('next-pwa')({
dest: 'public',
disable: process.env.NODE_ENV === 'development',
sw: 'sw.js'
})
const nextConfig = {
async redirects(){
return[
{
source: '/plain-language/accessible-webdesign',
destination: '/plain-language/for-disabled-persons',
permanent: 'true'
}
]
},
reactStrictMode: true,
swcMinify: true,
trailingSlash: false,
webpackDevMiddleware: config => {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300
}
return config
},
sassOptions: {
includePaths: [path.join(__dirname, 'styles')]
},
experimental: {
images: {
layoutRaw: true
}
},
images: {
/*unoptimized: true - for static export!*/
/*deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
formats: ['image/webp']*/
}
}
module.exports = withBundleAnalyzer(withPWA({nextConfig}));
My working solution was from here: https://stackoverflow.com/a/58182678/
I put a middleware.ts in the root-folder (right next to package.json, next.config.js etc).
And I wrote this inside:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export async function middleware(request: NextRequest) {
/* /accessible-webdesign --> /for-disabled-persons */
if (request.nextUrl.pathname.startsWith('/plain-language/accessible-webdesign')) {
return NextResponse.redirect(new URL('/plain-language/for-disabled-persons', request.url));
}
/* /another-url --> /another-redirect */
if (request.nextUrl.pathname.startsWith('/plain-language/another-url')) {
return NextResponse.redirect(new URL('/plain-language/another-redirect', request.url));
}
}
Not as beautiful, but working.

Nuxt vuex - moving store from Vue

I have been fiddling with moving a tutorial I did in Vue to Nuxt. I have been able to get everything working, however I feel I'm not doing it the "proper way". I have added the Nuxt axios module, but wasnt able to get it working, so I ended up just using the usual axios npm module. Here is my store:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(Vuex)
Vue.use(VueAxios, axios)
export const state = () => ({
events: []
})
export const mutations = {
setEvents: (state, events) => {
state.events = events
}
}
export const actions = {
loadEvents: async context => {
let uri = 'http://localhost:4000/events';
const response = await axios.get(uri)
context.commit('setEvents', response.data)
}
}
I would like to know how to re-write this store using the #nuxtjs/axios module. I also didnt think I'd need to import vuex here, but if I dont, my app doesn't work.
Thanks for any help!
Using the #nuxtjs/axios module, you can configure axios inside your nuxt.config.js:
// nuxt.config.js
export default {
modules: [
'#nuxtjs/axios',
],
axios: {
// proxy: true
}
}
You can use it inside your store (or components) with this.$axios
// In store
{
actions: {
async getIP ({ commit }) {
const ip = await this.$axios.$get('http://icanhazip.com')
commit('SET_IP', ip)
}
}
}

How to await an auth object with hooks? (MongoDB Stitch in React Native)

I am using React Native to build an app that relies on MongoDB Stitch for authentication. More often than not, the app crashes because the client object has not yet loaded when I use it in the following line of code. The error I get is the infamous TypeError: undefined is not an object followed by evaluating 'client.auth.user'.
import React from 'react';
import { View, Text } from 'react-native';
import { Stitch } from 'mongodb-stitch-react-native-sdk';
const APP_ID = '<my app ID>';
const client = Stitch.hasAppClient(APP_ID)
? Stitch.getAppClient(APP_ID)
: Stitch.initializeDefaultAppClient(APP_ID);
const { user } = client.auth;
const Home = () => {
return (
<View style={styles.home}>
<Text>HOME</Text>
<Text>Hi {user.profile.data.email}</Text>
</View>
);
};
export default Home;
const styles = {
home: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
};
The example provided with the MongoDB Stitch NPM package uses componentDidMount (see here), but I am trying to make this work using Hooks. I have tried useEffect, a bunch of if statements, async/await, placing the object in state with useState; No luck.
So yeah, you can use useEffect hook to instantiate the client and get the user info.
useEffect(() => {
_loadClient();
}, []);
const [client,setClient] = useState({});
const [user,setUser] = useState({});
_loadClient() {
Stitch.initializeDefaultAppClient('<your-client-app-id>').then(client => {
setClient(client);
if(client.auth.isLoggedIn) {
setUser( client.auth.user)
}
});
}
That should do it.

Getting an ' instance.requestPaymentMethod is not a function' in Braintree's sample

I'm getting an instance.requestpaymentmethod is not a function when I was just following along the tutorial for custom-field integration found here:
https://developers.braintreepayments.com/start/tutorial-hosted-fields-node
The error happens when I click on the "Pay" button.
Did anyone solve this problem? My assumption is that the code isn't updated or the script sources changed somewhat. If anyone from Braintree can actually help, that'll be great.
Thanks!
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
I took a look at the example code snippet in the guide you shared and I was able to find the culprit. First off, the error you're getting is expected as the requestPaymentMethod method actually belongs to our Drop-In UI solution and the Hosted Fields JS library doesn't have such module. I informed our Documentation team to get that code example updated.
That being said, you can find a working example in our Hosted Fields guide. If you check the function (hostedFieldsErr, hostedFieldsInstance) callback function, you'll see that the payment nonce is created by the tokenize function of the hostedFieldsInstance.
I also ran into this issue today. Use the following code in <script> tag. It will work for you.
var form = document.querySelector('#hosted-fields-form');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: '<YOUR_TOKENIZATION_KEY>'
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: '10/2019'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
console.log('Got a nonce: ' + payload.nonce);
$.ajax({
type: 'POST',
url: '<YOUR_API_URL>',
data: { 'paymentMethodNonce': payload.nonce }
}).done(function (result) {
hostedFieldsInstance.teardown(function (teardownErr) {
if (teardownErr) {
console.error('Could not tear down Drop-in UI!');
} else {
console.info('Drop-in UI has been torn down!');
$('#submit-button').remove();
}
});
if (result.success) {
$('#checkout-message').html('<h1>Success</h1><p>Your Drop-in UI is working! Check your sandbox Control Panel for your test transactions.</p><p>Refresh to try another transaction.</p>');
} else {
console.log(result);
$('#checkout-message').html('<h1>Error</h1><p>Check your console.</p>');
}
});
});
}, false);
});
});

Meteor can't subscribe to TAPi18n.Collection using TAPi18n.subscribe

I am using Meteor 1.5 and I am trying to subscribe to an i18n collection using these packages :
TAP:i18n
TAP:i18n-db
I ran meteor create --full <appname> to have the full scaffolded app.
Then I removed insecure and autopublish packages and added aldeed:simple-schema, audit-argument-checks and mdg:validated-method as recommended security mesures.
// imports/startup/server/fixtures.js
import { Meteor } from 'meteor/meteor';
import { Links } from '../../api/links/links.js';
Meteor.startup(() => {
// if the Links collection is empty
if (Links.find().count() === 0) {
const data = [
{
title: 'Do the Tutorial',
url: 'https://www.meteor.com/try',
i18n: {
'fr': {
title: 'FR Do the Tutorial',
},
},
createdAt: new Date(),
},
{
...
},
];
data.forEach(link => Links.insert(link));
}
});
// imports/api/links/links.js
import { Mongo } from 'meteor/mongo';
export const Links = new TAPi18n.Collection('links');
// imports/api/links/server/publications.js
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/tap:i18n';
import { Links } from '../links.js';
TAPi18n.publish('links.all', function () {
return Links.i18nFind();
});
// client/main.js
import { TAPi18n } from 'meteor/tap:i18n';
import '/imports/startup/client';
import '/imports/startup/both';
Meteor.startup(function() {
TAPi18n.setLanguage('en');
});
// imports/ui/components/info/info.js
import { Links } from '/imports/api/links/links.js';
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/tap:i18n';
import './info.html';
Template.info.onCreated(function () {
TAPi18n.subscribe('links.all');
});
Template.info.helpers({
links() {
return Links.find({});
},
});
...
In Chrome console using Meteor Dev-Tool, I can see this :
Chrome Meteor Dev-Tool screenshot
Basically it says unsubscribed from links.all (unrecognized subscription)
In the server console, I can see this :
Meteor Server Console
I did some work to include check statement in links.js above but even when I check all fields, the app can't subscribe to the publication.
Any idea or help would be much appreciated.
The packages are not mandatory for me if there is a better example/repo somewhere I can actually look at.
I thought you could not mix them up together. Use either TAP:i18n-db or TAP:i18n.
For examples have a look at the git repositories:
https://github.com/TAPevents/tap-i18n
https://github.com/TAPevents/tap-i18n-db
There are several examples you can have a look and decide to use only one of the packages.