Assign role after registration on Wix Velo - roles

I have made a register page and used the function assign role but the role is still not assigned to the member.
role.js:
import {roles} from 'wix-users-backend';
export function assignRole(roleId, memberId) {
return roles.assignRole(roleId, memberId, { suppressAuth: true })
.then( () => {
console.log("Role assigned to member");
})
.catch((error) => {
console.log(error);
});
Register page code:
import wixUsers from 'wix-users';
import {assignRole} from 'backend/role';
function register() {
let email = $w("#input2").value;
let password = $w("#input1").value;
let first = $w("#input4").value;
let last = $w("#input3").value;
wixUsers.register(email, password, {
contactInfo: {
"input4": first,
"input3": last
} })
.then((result) => {
let roleId="c37a89a2-012c-4090-833f-ce8f995cc912";
assignRole(roleId, result.user.id);})}
Please any help!

Related

vuex unknown action type: login

Login.vue
<script setup>
import { useLayout } from '#/layout/composables/layout';
import { ref, computed } from 'vue';
import AppConfig from '#/layout/AppConfig.vue';
import { decodeCredential } from 'vue3-google-login'
import {auth} from '../../../store/modules/auth.module';
import { useStore } from "vuex";
const store = useStore()
const { layoutConfig, contextPath } = useLayout();
const email = ref('');
const password = ref('');
const checked = ref(false);
const logoUrl = computed(() => {
return `${contextPath}layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`;
});
const callback = (response) => {
const userData = decodeCredential(response.credential);
// const authStore = auth;
// console.log(authStore.login());
if (userData.email=='****#gmail.com') {
return store.dispatch('login')
}
}
</script>
auth.module.js
import AuthService from "../../services/auth.service";
const user = JSON.parse(localStorage.getItem('token'));
const initialState = user
? { status: { loggedIn: true }, user }
: { status: { loggedIn: false }, user: null };
export const auth = {
namespaced: true,
state: initialState,
actions: {
login({ commit }, user) {
return AuthService.login(user).then(
user => {
commit('loginSuccess', user);
return Promise.resolve(user);
},
error => {
commit('loginFailure');
return Promise.reject(error);
}
);
},
logout({ commit }) {
AuthService.logout();
commit('logout');
},
},
mutations: {
loginSuccess(state, user) {
state.status.loggedIn = true;
state.user = user;
},
loginFailure(state) {
state.status.loggedIn = false;
state.user = null;
},
logout(state) {
state.status.loggedIn = false;
state.user = null;
},
}
};
auth.service.js
import axios from 'axios';
const API_URL = 'http://localhostGetToken';
class AuthService {
async login(user) {
const response = await axios
.post(API_URL, {
username: user.username='admin',
password: user.password='password'
});
if (response.data.accessToken) {
localStorage.setItem('token', JSON.stringify(response.token));
}
console.log(response);
return response.data;
}
async logout() {
localStorage.removeItem('token');
}
}
export default new AuthService();
Here i trying to login if email true to trigger login vuex.but i get a error [vuex] unknown action type: login
how to solve this?
You haven't included in your question how the auth store is linked to your application.
I'm guessing you have a main store and the auth store is one of its modules.
If my guess is true, you should dispatch auth/login, not login, since the main store doesn't have a login action.
Side note: I suggest you carefully read How to Ask, to improve the quality of your future questions.
The problems with your current question:
you posted too much irrelevant code and, at the same time, you haven't posted all the relevant code. You should have included:
a) the action deemed unknown (everything else in that store is irrelevant for this question)
b) how the store is linked to the app (main store + how the store is instantiated in the app) - these bits are missing
c) how you're consuming the action in the component (everything else in the component is irrelevant for the question)
you started with the code. Always start by explaining the problem, so when people look at the code, they know what to look for (and skip the irrelevant parts). This is also helpful for future users with a similar problem: they'll be able to quickly understand if your question is relevant for their problem.
The more users find the question useful, the more chances for it to get upvoted.
Another side-note: the condition used to dispatch is, most likely, wrong. It is only true when the email is actually '****#gmail.com'.
You should probably use if (userData.email.endsWith('#gmail.com')).

react-native-storage returning undefined from local storage

I am having some difficulties on executing local storage operations...
"react-native": "0.64",
"react-native-storage": "^1.0.1"
I'm using react-native-storage, as pointed in title, and I have created two simple methods for handling Writing and Reading:
import Storage from 'react-native-storage';
import AsyncStorage from '#react-native-community/async-storage';
const storage = new Storage({
size: 1000,
storageBackend: AsyncStorage,
defaultExpires: null,
enableCache: true,
sync: {
return: 'No data.'
}
});
const saveToLocalStorage = (key: any, data: any) => {
storage.save({
key,
data,
expires: null
})
}
const getFromLocalStorage = (key: any) => {
storage.load({
key,
autoSync: true
})
.then(data => {
return { data }
})
.catch(err => { });
}
export { saveToLocalStorage, getFromLocalStorage }
As you can see, it's pretty much the code example from https://www.npmjs.com/package/react-native-permissions.
At the App.tsx file, I do the following:
useEffect(() => {
saveToLocalStorage('test', 'test data');
const test = getFromLocalStorage('test');
}, [])
which returns undefined.
But if in the method getFromLocalStorage I replace
.then(data => {
return { data }
})
for
.then(data => console.warn(data));
the result is the image from bellow:
In short:
If the function returns the object from the storage, it brings undefined.
If the function returns a console.log from the storage, it brings what I've written on it.
because return { data } is not a valid expression for async functions
just use AsyncStorage, react-native-storage is not needed unless you develop for both mobile and web
useEffect(() => {
await AsyncStorage.setItem('test', 'myValue');
const value = await AsyncStorage.getItem('test');
console.log(value);
}, [])

relay subscription onNext not triggered on react-native

I am a subscription setup but onNext is not getting triggered I am not sure why since this is my first time implementing subscription and docs was not much help with the issue.
Here are the code implementations:
import {
graphql,
requestSubscription
} from 'react-relay'
import environment from '../network';
const subscription = graphql`
subscription chatCreatedSubscription{
chatCreated{
id
initiate_time
update_time
support_id
category_id
email
name
}
}
`;
function chatCreated(callback) {
const variables = {};
requestSubscription(environment, {
subscription,
variables,
onNext: () => {
console.log("onNext");
callback()
},
updater: () => {
console.log("updater");
}
});
}
module.exports = chatCreated;
and here is my network for the subscription
import { Environment, Network, RecordSource, Store } from "relay-runtime";
import Expo from "expo";
import { SubscriptionClient } from "subscriptions-transport-ws";
import { WebSocketLink } from 'apollo-link-ws';
import { execute } from 'apollo-link';
import accessHelper from "../helper/accessToken";
const networkSubscriptions = async (operation, variables) => {
let token = await accessHelper();
if (token != null || token != undefined) {
const subscriptionClient = new SubscriptionClient("ws://localhost:3000/graphql",
{
reconnect: true,
connectionParams: {
Authorization: token,
},
});
execute(new WebSocketLink(subscriptionClient), {
query: operation.text,
variables,
});
}
}
const network = Network.create(fetchQuery, networkSubscriptions);
const store = new Store(new RecordSource());
const environment = new Environment({
network,
store
});
export default environment;
the subscription is called in a componentDidMount method on a component it executes but the onNext method inside the subscription is never triggered when new information is added to what the subscription is listening to.
so i figured out that my issue was the network js not being setup properly and the version of subscription-transport-ws. i added version 0.8.3 of the package and made the following changes to my network file:
const networkSubscriptions = async (config, variables, cacheConfig, observer) => {
const query = config.text;
let token = await accessHelper();
if (token != null || token != undefined) {
const subscriptionClient = new SubscriptionClient(`ws://${api}/graphql`,
{
reconnect: true,
connectionParams: {
Authorization: token,
},
});
subscriptionClient.subscribe({ query, variables }, (error, result) => {
observer.onNext({ data: result })
})
return {
dispose: subscriptionClient.unsubscribe
};
}
}
i hope this helps you if you get stuck with the same issue as mine.

localStorage.getItem() always returns null even when value exists

Im not sure If I am doing something wrong or if I have a typo somewhere, but I am trying to compare dates in a vue project but the value I pull from my local storage always returns null even when I can see the value clearly exists when I check my local storage. so here is the set up.
after making a request I set the expires date in local storage like so
retrieveToken({ commit }, credentials) {
return new Promise((resolve, reject) => {
axios.post('/login', {
username: credentials.username,
password: credentials.password,
})
.then(response => {
const token = response.data.access_token
const date = new Date(moment().add(30, 'seconds').toDate());
localStorage.setItem('expires_on', date)
localStorage.setItem('access_token', token)
resolve(response)
})
.catch(error => {
console.log(error.response.data)
reject(error)
})
})
},
I can then see that the expires on has been placed in my local storage
I then want to use a getter to retrieve that value like so
tokenExpires() {
return localStorage.getItem('expires_on')
},
So i can use like this
computed: {
...mapGetters(['tokenExpires']),
},
methods: {
destroySessionIfTokenIsExpired() {
const current = new Date(moment())
const expires = this.tokenExpires
const currentDate = moment(current).format('YYYYMMDDHHMMSS')
const expiresDate = moment(expires).format('YYYYMMDDHHMMSS')
console.log(this.tokenExpires)
console.log(expiresDate)
if(currentDate >= expiresDate) {
this.$store.dispatch('destroyToken')
.then(() => {
this.$router.push('/login')
alert('Your Session Has Expired, Please Log Back In')
})
} else return;
}
}
but when I run this method and console.log(this.tokenExpires) it returns null and I am not sure why. If anybody can see what I am doing wrong please let me know!!
*Update, my issue is that I am trying to watch the routes and run a comparison of timestamps to see if the session is still valid but as pointed out, the getter does not have enough time to compute the value before the method runs, so any suggestions on how I could get around that would be awesome. here is the route watch method
watch: {
'$route': function(to, from) {
this.destroySessionIfTokenIsExpired()
}
},
thanks to #YongQuan I have this solution.
methods: {
...mapActions(['destroyToken']),
destroySessionIfTokenIsExpired() {
const expiresOn = localStorage.getItem('expires_on')
const expiresDate = moment(expiresOn).format('YYYYMMDDHHMMSS')
if(expiresOn == null) return;
const current = new Date(moment())
const currentDate = moment(current).format('YYYYMMDDHHMMSS')
if(currentDate >= expiresDate) {
this.$store.dispatch('destroyToken')
this.$router.push('/login')
} else return;
}
},
watch: {
'$route': function(to, from) {
this.destroySessionIfTokenIsExpired()
}
},
Instead of using a getter I just set the `localStorage.getItem('expires_on') to a variable inside the method. Thanks #YongQuan

Computed Getter causes maximum stack size error

I'm trying to implement the following logic in Nuxt:
Ask user for an ID.
Retrieve a URL that is associated with that ID from an external API
Store the ID/URL (an appointment) in Vuex
Display to the user the rendered URL for their entered ID in an iFrame (retrieved from the Vuex store)
The issue I'm currently stuck with is that the getUrl getter method in the store is called repeatedly until the maximum call stack is exceeded and I can't work out why. It's only called from the computed function in the page, so this implies that the computed function is also being called repeatedly but, again, I can't figure out why.
In my Vuex store index.js I have:
export const state = () => ({
appointments: {}
})
export const mutations = {
SET_APPT: (state, appointment) => {
state.appointments[appointment.id] = appointment.url
}
}
export const actions = {
async setAppointment ({ commit, state }, id) {
try {
let result = await axios.get('https://externalAPI/' + id, {
method: 'GET',
protocol: 'http'
})
return commit('SET_APPT', result.data)
} catch (err) {
console.error(err)
}
}
}
export const getters = {
getUrl: (state, param) => {
return state.appointments[param]
}
}
In my page component I have:
<template>
<div>
<section class="container">
<iframe :src="url"></iframe>
</section>
</div>
</template>
<script>
export default {
computed: {
url: function (){
let url = this.$store.getters['getUrl'](this.$route.params.id)
return url;
}
}
</script>
The setAppointments action is called from a separate component in the page that asks the user for the ID via an onSubmit method:
data() {
return {
appointment: this.appointment ? { ...this.appointment } : {
id: '',
url: '',
},
error: false
}
},
methods: {
onSubmit() {
if(!this.appointment.id){
this.error = true;
}
else{
this.error = false;
this.$store.dispatch("setAppointment", this.appointment.id);
this.$router.push("/search/"+this.appointment.id);
}
}
I'm not 100% sure what was causing the multiple calls. However, as advised in the comments, I've now implemented a selectedAppointment object that I keep up-to-date
I've also created a separate mutation for updating the selectedAppointment object as the user requests different URLs so, if a URL has already been retrieved, I can use this mutation to just switch the selected one.
SET_APPT: (state, appointment) => {
state.appointments = state.appointments ? state.appointments : {}
state.selectedAppointment = appointment.url
state.appointments = { ...state.appointments, [appointment.appointmentNumber]: appointment.url }
},
SET_SELECTED_APPT: (state, appointment) => {
state.selectedAppointment = appointment.url
}
Then the getUrl getter (changed its name to just url) simply looks like:
export const getters = {
url: (state) => {
return state.selectedAppointment
}
}
Thanks for your help guys.