I'm trying to use the ToastController of Ionic outside an vue instance; i've build an separated actions file which will be loaded inside the vue instance itself which handles a request. During this request it does some validations and i would like to throw a toast while something happened. In the vue instance i could do this.$ionic.toastController.create() which is working fine but in this other file there is no vue instance available so i'd tried to import the ToastController there but am not able to make this work.
Someone who can point me in the right direction with this?
I've already tried few options and searching the internet for this; since ionic 4 with vue.js is still in alpha there is very low support at the moment. I'd also use the #modus/ionic-vue instance which is working better then the original from ionic itself at the moment
The actual code will be called during a this.$store.dispatch(RESERVATION_REQUEST) call see example:
import { ToastController } from '#modus/ionic-vue'
import axios from 'axios'
const state = {
status: '',
classes: {},
}
const getters = {
//
}
const actions = {
[RESERVATION_REQUEST]: ({ commit, dispatch }, data) => {
return new Promise(( resolve, reject ) => {
axios({ url: 'reservation/create', data: { lesson: data.lesson, date: data.date, team: data.team }, method: 'POST' })
.then(response => {
ToastController.create({
duration: 2000,
header: 'Confirmation',
message: 'Success',
position: 'top',
showCloseButton: true,
closeButtonText: 'Ok',
}).then(toast => toast.present());
resolve(response)
})
.catch(error => {
ToastController.create({
duration: 2000,
header: 'failed',
message: error.toString(),
position: 'top',
showCloseButton: true,
closeButtonText: 'Ok',
}).then(toast => toast.present());
reject(error)
});
});
},
}
const mutations = {
//
}
export default {
state,
getters,
actions,
mutations,
}
The above code will be called like this:
toggleReservation(lesson, date) {
const team = this.$store.getters.getCurrentId;
this.$store.dispatch(RESERVATION_REQUEST, { lesson, date, team });
}
Would be nice if someone could help me with this; looking for at for a few days right now having the feeling i'm on the right track but can't find the solution yet.
You can do directly then and catch on the $store.dispatch in your vue instance
store:
const actions = {
[RESERVATION_REQUEST]: ({ commit, dispatch }, data) => {
return new Promise(( resolve, reject ) => {
axios({ url: 'reservation/create', data: { lesson: data.lesson, date: data.date, team: data.team }, method: 'POST' })
.then(response => {
resolve(response)
})
.catch(error => {
reject(error)
});
});
},
}
Vue file:
toggleReservation(lesson, date) {
const team = this.$store.getters.getCurrentId;
this.$store.dispatch(RESERVATION_REQUEST, { lesson, date, team })
.then(response => {
this.$ionic.toastController.create({
duration: 2000,
header: 'Confirmation',
message: 'Success',
position: 'top',
showCloseButton: true,
closeButtonText: 'Ok',
}).then(toast => toast.present());
})
.catch(error => {
this.$ionic.toastController.create({
duration: 2000,
header: 'failed',
message: error.toString(),
position: 'top',
showCloseButton: true,
closeButtonText: 'Ok',
}).then(toast => toast.present());
});
}
PS: axios return a promise so if you want you can do return it directly in the store
const actions = {
[RESERVATION_REQUEST]: ({ commit, dispatch }, data) => {
return axios({ url: 'reservation/create', data: { lesson: data.lesson, date: data.date, team: data.team }, method: 'POST' })
},
}
Related
// how can I use the promise of toastify like I want to show spinner while fetching data then message success or failed
// but I am getting error in bellow code
const fetch = () => {
axios
.get("https://restcountries.com/v2/name/india")
.then((res) => {
toast.promise({
pending:"pending",
success:"success",
error:"rejected"
} )
console.log(res);
})
.catch((err) => {
toast.error("🦄 failed", {
position: "top-center",
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined
});
});
};
According to toast API https://fkhadra.github.io/react-toastify/promise/ the syntax should be
const myPromise = fetchData();
toast.promise(myPromise, {
loading: 'Loading',
success: 'Got the data',
error: 'Error when fetching',
})
An example which can be found on https://codesandbox.io/s/twilight-bash-jzs24y?file=/src/App.js
export default function App() {
const myPromise = new Promise((resolve) =>
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then((response) => response.json())
.then((json) => setTimeout(() => resolve(json), 3000))
// setTimeout just for the example , cause it will load quickly without it .
);
useEffect(() => {
toast.promise(myPromise, {
pending: "Promise is pending",
success: "Promise Loaded",
error: "error"
});
}, []);
return (
<div className="App">
<ToastContainer />
</div>
);
}
If you are not using promise. Use toast.loading.
(DOCS: https://fkhadra.github.io/react-toastify/promise/#toastloading)
const getData = () => {
const id = toast.loading("Please wait...")
axios.get(`some-url`)
.then(res => {
toast.update(id, {render: "All is good", type: "success", isLoading: false});
}).catch(err => {
toast.update(id, {render: "Something went wrong", type: "error", isLoading: false });
});
}
If it is not working then store toast id in useRef and then it will work.
You can use toast.update (https://fkhadra.github.io/react-toastify/update-toast)
const toastId = useRef(null)
const fetch() => {
toastId.current = toast.loading("Loading...")
axios
.post(...)
.then(() => {
toast.update(toastId.current, {
render: "Your message...",
type: "success",
isLoading: "false"
}
})
.catch(() => {
toast.update(toastId.current, {
render: "Your message...",
type: "error",
isLoading: "false"
}
})
}
I have been working on a project where I am trying to update my selected data but Axios didn't Update it even after giving a success msg.
User Response it returns from axios:-
completed: true
date: "2021-02-28"
mupp_path: "PATH 1 - LIVING YOUR WHY - Build/Apply/Inspire/Spread (BAIS) – Finding & Achieving Meaning and Purpose in work and life"
project_name: "Design and Test the Training Content for the i-Infinity 3 verticals "
selected: true
task_id: 14
task_name: "This is adding a new task to chekc full inbox functionality "
task_type: "THIS_WEEK"
Actions.js
export const taskTodayUnselect = (id) => async (dispatch) => {
try {
dispatch({ type: types.UNSELECTED_TASK_TODAY_REQUEST });
const { data } = await axios.put(
selectTaskForToday,
{
task_id: id,
selected: false,
},
{
headers: {
Authorization: `JWT ${token}`,
},
}
);
if (data) {
return dispatch({ type: types.UNSELECTED_TASK_TODAY_SUCCESS, payload: data });
}
} catch (error) {
return dispatch({ type: types.UNSELECTED_TASK_TODAY_FAILURE, payload: error });
}
};
thisweek.js
export default function ThisWeek() {
const unselectTaskTodayAPI = (id) => {
dispatch(taskTodayUnselect(id)).then((response) => {
let result = response.payload;
console.log(result);
if (result.success === 'true') {
notifySuccess(result.message);
fetchTaskData(categoryID);
}
});
};
const selectTask = (item) => {
if (item.selected) {
unselectTaskTodayAPI(item);
console.log('unselect');
} else {
selectTaskTodayAPI(item.task_id);
}
};
return (
<TaskDataComponent
item={item}
key={item.task_id}
label="This Week"
selectTask={selectTask}
/>
);
Don't Worry about the TaskDataComponent , it only handle the onClick function which invoke the selectedTask function
After a new project is created, I'd like to route the user to another page so they can add more information to the project.
This is working:
createProject() {
ProjectService.createProject(this.project)
.then(response => {
this.$router.push({
name: "project-update",
params: { id: response.data.data.id }
});
})
}
I'd like to use vuex to handle all this, but this is not working.
createProject() {
this.$store
.dispatch("project/postProject", this.project)
.then(response => {
this.$router.push({
name: "project-update",
params: { id: response.data.data.id }
});
})
.catch(() => {});
}
The error I'm getting is: "state.projects.push is not a function"
This is my postProject action in Vuex:
postProject({ commit, dispatch }, project) {
return ProjectService.createProject(project)
.then(() => {
commit('ADD_PROJECT', project);
const notification = {
type: 'success',
message: 'Your project has been created!'
};
dispatch('notification/add', notification, { root: true });
})
.catch(error => {
const notification = {
type: 'error',
message: 'There was a problem creating your project: ' + error.message
};
dispatch('notification/add', notification, { root: true });
throw error;
});
}
Looks like the context of 'this' is not reaching the router or the push function therein. How can I access the router and route to that next page?
What you can do is import your router module into your vuex module like so:
import {router} from "../main.js"
// or
import router from '../router'
export default {
actions: {
createProject () {
this.$store
.dispatch("project/postProject", this.project)
.then(response => {
router.push({
name: "project-update",
params: { id: response.data.data.id }
})
})
.catch(() => { })
}
}
}
I have a same issue but I solved by doing this:
this.$router.replace("/");
Having issue in vuex and nuxt store by using this : this.$router.push("/");
I have been learning react for a while and have been working on creating a pet project. My friend created a test case which tests out some notification message from a method. This method in turn will use a constant from another class.
Below notification component utilizes a set of props(especially the partner props) passed over from routes.js.
class Notification extends Component {
constructor(props) {
super(props);
this.state = {
orientation: "ltr",
services: {
"applications": [],
"eta": "",
"start": ""
},
statuses: {},
locale_date: new Date(),
modal: {
open: false,
header: null,
desription: null
},
// This shouldn't be hardcoded but there are issues with passing this in as a prop in Routes.js
partner: props.partner
}
this.refreshEndpoints();
}
refreshEndpoints = () => {
const ref = this;
axios
.get(this.state.partner.get_device_status_url)
.then(response => {
var statuses = response.data;
if((typeof statuses) !== 'object') return false;
ref.setState({
statuses: statuses
});
}).catch(error => {
});
}
handleCreateNotification = () => {
const ref = this;
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(ref.state.services)
};
adalApiFetch(fetch, this.state.partner.get_endpoint_notifications_banner, options)
.then(response => {
ref.setState({
modal: {
open: true,
header: "Success",
description: "Successfully Created Notification"
}
});
})
.catch(function (error) {
ref.setState({
modal: {
open: true,
header: "Error",
description: "Failed to Create Notification"
}
});
});
}
handleDeleteNotification = () => {
const ref = this;
const options = {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(ref.state.services)
};
adalApiFetch(fetch, this.state.partner.get_endpoint_notifications_banner, options)
.then(response => {
ref.setState({
modal: {
open: true,
header: "Success",
description: "Successfully Deleted Notification"
}
});
})
.catch(function (error) {
ref.setState({
modal: {
open: true,
header: "Error",
description: "Failed to Delete Notification"
}
});
});
}
In routes.js I have route for calling out the above component which passes the props for partner.
<ProtectedNotificationPage orientation={orientation} partner={PartnerOne}/>
ParnerOne.js:
export const get_endpoint_notifications_banner = "<some url>"
export const get_device_status_url = "<some url>"
<class components>
I want to utilize the above const in notification component. And I was able to accomplish that using props.partner inside the state method.
But below test case is failing due to undefined property which is strange. But the notification functionality completely works fine. clearing and adding notification has no issues.
describe('Notification component', () => {
it('handleCreateNotification - Success', async () => {
const wrapper = shallow(<Notification />);
await wrapper.instance().handleCreateNotification();
expect(wrapper.state().modal).toEqual(
{
open: true,
header: "Success",
description: "Successfully Created Notification"
}
);
});
it('handleDeleteNotification', async () => {
const wrapper = shallow(<Notification />);
await wrapper.instance().handleDeleteNotification();
expect(wrapper.state().modal).toEqual(
{
open: true,
header: "Success",
description: "Successfully Deleted Notification"
}
);
});
I apologize for my lack of knowledge.. But this is something I couldn't figure out over tutorials/blogs. And I really appreciate if anyone able to point out the issue or reference for fixing this.
I tried utilizing bind across methods, which is something I thought might fix. But didn't workout. Apart from that I also tried accessing the props directly
like this.props.partner.get_device_status_url.. And still test case were failing.
I would suggest the following:
Importing into Notification.js:
const { get_endpoint_notifications_banner, get_device_status_url } = '<path_to_file>'.
You can now access these variables directly inside Notification.js.
Test case was having some issue. When I passed the partner one as props to my test case. It fixed the issue. It was looking for missing props
I'm extremely new when it comes to using VueJS and so I am working on a small App that should list out an Authenticated person's Github repositories.
I'm having trouble when it comes to being able to access or even traverse the Array in the Picture below. I keep getting an error of undefinedif I try userRepos. Please see my code below.
I do apologize for the "Wall of Code". But I thought these javascript code snippets are the most pertinent to the issue.
This is the GitHub repo I am using as the boilerplate for this project. GitHub-Electron-Vue-OAuth
const getAxiosClient = (state) => {
return axios.create({
baseURL: state.server.url, // this is "https://api.github.com
headers: {
'Authorization': 'token ' + state.session.access_token
},
responseType: 'json'
})
}
// Mutation
[types.SET_USER_REPOS](state, repos) {
state.session.repos = repos;
},
// State Object
const state = {
server: {
url: 'http://api.github.com'
},
session: {
access_token: window.localStorage.getItem('access_token'),
ready: false,
authenticated: false,
user: {}
}
};
// Actions
export const getRepos = ({
commit,
state
}) => {
return new Promise((resolve, reject) => {
getAxiosClient(state).get('/user/repos').then(response => {
commit(types.SET_USER_REPOS, response.data)
resolve(response.data)
}, err => {
console.log(err)
reject(err)
})
})
}
export const userRepos = (state) => {
console.log(state.session.repos)
return state.session.repos;
}
<template lang="jade">
.home
span Hello {{ username }}
span {{ userRepos }}
</template>
<script>
export default {
name: 'home',
computed: {
username() {
return this.$store.getters.username;
},
userRepos() {
return this.$store.getters.userRepos;
}
},
// TODO: Push this in router
beforeRouteEnter(to, from, next) {
next(vm => {
if (!vm.$store.getters.isAuthenticated) {
vm.$router.push({
name: 'login'
});
} else {
next();
}
});
}
}
</script>