inter component communication in nuxt js - vue-component

I am trying to call a function of a component from another component.
In the called function there is a dispatch to store which works if call it from the same component but gives an error if the call is made from other components.
Same with the $emit and $on
Cannot read property 'dispatch' of undefined
Component from where the function is called
<template>
<div>
<button #click="doSubmit()">submit</button>
</div>
</template>
<script>
import empinfo from '../components/empinfo'
export default {
components: {
},
data() {
return {
infoEmp: {
}
}
},
methods: {
doSubmit() {
empinfo.methods.putEmpinfo()
console.log('this sendEmpinfo', empinfo.methods.putEmpinfo())
// this.$nuxt.$on('EMP_INFO', (data) => {
// this.infoEmp = data
// console.log('in data', data)
// })
console.log('infoEmp', this.infoEmp)
}
}
}
</script>
Here
The function called
<script>
export default {
data() {
return {
empInfo: {
lastName: "",
firstName: "",
middleIntial: "",
otherLastName: "",
address: "",
apartmentNo: "",
city: [],
}
}
},
computed: {
compEmpinfo() {
// console.log('emp inform', event)
// this.$store.dispatch('formdata/EMP_INFO', this.empInfo)
console.log("this is ", this)
const some = this.$store.dispatch("formdata/EMP_INFO", this.empInfo)
console.log("log sto", some)
return some
// return this.$nuxt.$emit('EMP_INFO', this.empInfo)
}
},
methods: {
putEmpinfo() {
// console.log('emp inform', event)
// this.$store.dispatch('formdata/EMP_INFO', this.empInfo)
//console.log("this is ", this)
try {
const some = this.$store.dispatch("formdata/EMP_INFO",
this.empInfo)
console.log("log some", some)
} catch (error) {
console.log("try clatch", error)
}
// return this.$nuxt.$emit('EMP_INFO', this.empInfo)
},
testcall() {
console.log("test call works")
},
sendEmpinfo() {
return this.empInfo
}
}
}
</script>

Related

Data is not fetching properly in SSG Next.js

While creating the post (for the blog) using Jodit Editor, I used to directly save it's output (html string) into mongo.
Then after adding SSG, at the build time, the (consoled) fetched data appears as this.
Whereas simply fetching the api shows data correctly. here
Code of getStaticProps & getStaticPaths
export async function getStaticProps({ params }) {
try {
const { data } = await axios.post(baseUrl + getPostBySlug, { slug: params?.slug });
console.log({ slug: params?.slug }, 'data 2 ->', data); // here is the data consoled
return {
props: { post: data?.data ?? null },
revalidate: 10,
}
}
catch (err) {
return {
props: { post: null },
revalidate: 10,
}
}
}
export async function getStaticPaths() {
try {
const res = await fetch(baseUrl + getAllPosts, { method: 'GET' });
const data = await res?.json();
if (data?.success && data?.data) {
return {
paths: data?.data?.map(({ slug }) => ({ params: { slug } })),
fallback: true,
}
}
else {
return {
paths: [{ params: { slug: '/' } }],
fallback: true,
}
}
}
catch (err) {
return {
paths: [{ params: { slug: '/' } }],
fallback: true,
}
}
}
Final output, a SSG page but with no data init -> here
You need to update to Axios ^1.2.1 - there was an issue with previous versions.
You can set the headers as a temporary solution to prevent this from happening.
await axios.post("your/api/url",{
headers: { Accept: 'application/json', 'Accept-Encoding': 'identity' },
{ slug: "url-slug" }
)

should I wrap my try catch block inside of the for loop RTK QUERY?

I use rtk query and make optimistic UI. So I select by endpoints and change the data but there is one thing. I have a constant varibale "patchResult" in my for loop and outer for loop I await my query fullfilled. So I can not patchResult.undo() because patchResult variable is inside the for loop and my try catch block is outer the for loop so I dont have access to the variable. Should I put the try catch block in the for loop or is it bad ?
async onQueryStarted({ user_id }, { dispatch, queryFulfilled, getState }) {
for (const { endpointName, originalArgs } of Api.util.selectInvalidatedBy(getState(), [{ type: 'USER'}])) {
const patchResult = dispatch(
UserApi.util.updateQueryData('users', originalArgs, (draft) => {
return {
...draft,
user: {
...draft.user,
is_follow: !draft.user.is_follow
}
}
})
);
}
try {
await queryFulfilled
} catch {
patchResult.undo();
}
You will probably need an array of patches:
async function onQueryStarted(
{ user_id },
{ dispatch, queryFulfilled, getState }
) {
let allPatches = [];
for (const { endpointName, originalArgs } of Api.util.selectInvalidatedBy(
getState(),
[{ type: "USER" }]
)) {
const patchResult = dispatch(
UserApi.util.updateQueryData("users", originalArgs, (draft) => {
return {
...draft,
user: {
...draft.user,
is_follow: !draft.user.is_follow,
},
};
})
);
allPatches.push(patchResult);
}
try {
await queryFulfilled;
} catch {
for (const patchResult of allPatches) {
patchResult.undo();
}
}
}

Unable to upload image from RN app to meteor backend

I want to upload image from my RN app to meteor backend. I am using "react-native-image-picker": "^0.26.7" for getting imagefile from gallery or camera and uploading to meteor using package react-native-meteor to collectionFs this is my code of RN app where I am calling meteor method for image upload as soon as user select image:
_handleSelectFile() {
const { order } = this.state;
var options = {
title: 'Select Avatar',
storageOptions: {
skipBackup: true,
path: 'images'
}
};
ImagePicker.showImagePicker(options, (response) => {
if (response.didCancel) {
console.log('User cancelled image picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else {
// let source = { uri: response.uri };
// You can also display the image using data:
let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
order: {
...order,
fileName: response.fileName
}
});
let fileData = response.data;
// const body = new FormData();
// body.append('file',fileData);
var photo = {
url: fileData,
type: 'image/jpeg',
name: 'photo.jpg',
};
Meteor.FSCollection('orderImages').insert(photo, function (err, res) {
if (err) {
console.log('error during uploading');
} else {
console.log('uploading successfully');
// _this.props.navigator.pop();
}
});
}
});
}
and this is my server side code:
export const Orders = new Mongo.Collection('orders');
export const OrderImages = new FS.Collection("orderImages", {
filter: {
maxSize: 1048576,
allow: {
contentTypes: ['image/*'],
}
},
stores: [new FS.Store.FileSystem("orderImages")]
});
if (Meteor.isServer) {
OrderImages.allow({
insert: function () {
return true;
}
});
}
and I am getting error like this:
ExceptionsManager.js:65
Cannot read property 'apply' of undefined

Watching computed properties

I have a component with the following hash
{
computed: {
isUserID: {
get: function(){
return this.userId?
}
}
}
Should I be watching isUserID or userId for changes? Can you watch computed properties?
Yes, you can setup watcher on computed property, see the fiddle.
Following is the code to set watch on computed property:
const demo = new Vue({
el: '#demo',
data() {
return {
age: ''
};
},
computed: {
doubleAge() {
return 2 * this.age;
}
},
watch: {
doubleAge(newValue) {
alert(`yes, computed property changed: ${newValue}`);
}
}
});
computed: {
name: {
get: function(){
return this.name;
}
}
},
watch: {
name: function(){
console.log('changed');
}
}
This way we can watch over the computed property if it is changed we get notified on the console.
Here's how you do it in Vue 3 with Composition API:
<script setup>
import { ref, computed, watch } from 'vue'
const variable = ref(1)
const computedProperty = computed(() => {
return variable.value * 2
})
watch(computedProperty, (newValue, oldValue) => {
console.log('computedProperty was ' + oldValue + '. Now it is ' + newValue + '.')
})
</script>
<template>
<button #click="variable++">Click me</button>
</template>

Vuex state change is not reactive

I am working with Vuex and Firebase Auth system.
I just want to store with Vuex the user object that i get from:
firebase.auth().getCurrentUser
so that every time it changes, it updates the views.
But i ve troubles with this.
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {
loggedIn: false,
data: null
}
},
getters: {
user(state){
return state.user
}
},
mutations: {
SET_LOGGED_IN(state, value) {
state.user.loggedIn = value;
},
SET_USER(state, data) {
state.user.data = data;
}
},
actions: {
fetchUser({ commit }, user) {
commit("SET_LOGGED_IN", user !== null);
if (user) {
commit("SET_USER", user);
} else {
commit("SET_USER", null);
}
}
}
});
Account.vue
<template>
<ion-item>
<ion-label #click="openModal()" position="stacked">Your name</ion-label>
{{user.data.displayName}}
</ion-item>
</template>
computed: {
// map `this.user` to `this.$store.getters.user`
...mapGetters({
user: "user"
})
},
methods: {
openModal() {
let us = this.$store.getters.user;
return this.$ionic.modalController
.create({
component: Modal,
componentProps: {
data: {
content: 'New Content',
},
propsData: {
pro: us.data.displayName
},
},
})
.then(m => m.present())
},
.
.
.
</script>
Modal.vue
<template>
<ion-app>
<h1>MODAL</h1>
<ion-input :value="prop" #input="prop = $event.target.value"></ion-input>
<ion-button #click="clos()">Save</ion-button>
</ion-app>
</template>
<script>
import firebase from "firebase";
export default {
props:['pro'],
data(){
return{
prop: this.pro
}
},
methods:{
clos(){
let vm = this;
let user = firebase.auth().currentUser;
window.console.log("updating",vm.prop)
user.updateProfile({
displayName: vm.prop
}).then(function(){
user = firebase.auth().currentUser;
vm.$store.dispatch("fetchUser",user);
}).catch(function(err){
window.console.log("err",err);
})
this.$ionic.modalController.dismiss();
}
}
}
</script>
I can see using Vue Dev Tools that when I dispatch the new user in Modal.vue
vm.$store.dispatch("fetchUser",user);
that the Vuex state is correctly updated, but the view in Account.vue is not.
But if I press the button 'commit this mutation' in the dev tools the view updates!
How can I fix this behavior?
try this solution:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {
loggedIn: false,
data: null
}
},
getters: {
user(state){
return state.user;
},
userData(state){
return state.user.data;
}
},
mutations: {
SET_LOGGED_IN(state, value) {
state.user.loggedIn = value;
},
SET_USER(state, data) {
state.user.data = data;
}
},
actions: {
fetchUser({ commit }, user) {
commit("SET_LOGGED_IN", user !== null);
if (user) {
commit("SET_USER", user);
} else {
commit("SET_USER", null);
}
}
}
});
Account.vue
<template>
<ion-item>
<ion-label #click="openModal()" position="stacked">Your name</ion-label>
{{user.displayName}}
</ion-item>
</template>
computed: {
// map `this.user` to `this.$store.getters.user`
...mapGetters({
user: "userData"
})
},
methods: {
openModal() {
let us = this.$store.getters.userData;
return this.$ionic.modalController
.create({
component: Modal,
componentProps: {
data: {
content: 'New Content',
},
propsData: {
pro: us.displayName
},
},
})
.then(m => m.present())
},
.
.
.
</script>
You can try this:
SET_USER(state, data) {
Vue.$set(state.user, 'data', data)
}

Resources