I want to display the error messages I am receiving from my backend in an alert, whenever my login failes:
My login-button triggers this function from my user.actions:
function login(username, password) {
return dispatch => {
dispatch(request({ username }));
userService.login(username, password)
.then(
user => {
dispatch(success(user));
history.goBack();
},
error => {
dispatch(failure(error.toString()));
dispatch(alertActions.error(error.toString()));
}
);
};
function request(user) { return { type: userConstants.LOGIN_REQUEST, user } }
function success(user) { return { type: userConstants.LOGIN_SUCCESS, user } }
function failure(error) { return { type: userConstants.LOGIN_FAILURE, error } }
}
My alert.reducer looks as following:
import { alertConstants } from '../_constants';
export function alert(state = {}, action) {
switch (action.type) {
case alertConstants.SUCCESS:
return {
type: 'alert-success',
message: action.message
};
case alertConstants.ERROR:
return {
type: 'alert-danger',
message: action.message
};
case alertConstants.CLEAR:
return {};
default:
return state
}
}
In my App.js I receive this state with mapStateToProps:
function mapStateToProps(state) {
const { alert } = state;
return {
alert
};
}
After that, I want to display an alert with the alert message:
{alert.message &&
alert(alert.message)
}
Can you help me with that?
your action/reducer code looks ok, I think maybe it is a conflict with the props name and the native alert function.
Have you tried to change the props names? Something like:
function mapStateToProps(state) {
const { alert } = state;
return {
alertState: alert
};
}
and
{ alertState.message && alert(alertState.message) }
Related
Please how can i achieve this!
I have a switch button i'll like to use to control boolean value (true/false) in my MongoDB database
isBanned: {
type: Boolean,
default: false,
},
my button
<b-form-checkbox
v-model="post.isBanned"
switch
#change="isBannedUser($event, post._id)"
>
{{ post.isBanned }})
</b-form-checkbox>
What I expect to happen!
If I toggle the switch checkbox from the frontend (Nuxt), I want isbanned to be set to true and change the default false value in database. If I toggle the same checkbox again next time, I want false value to be sent to the backend and change the db value from true to false and vice versa
<script>
export default {
data() {
return {
post: {
isBanned: null,
},
}
},
methods: {
async isBannedUser(e, id) {
const data = {
isBanned: this.post.isBanned,
}
try {
const response = await this.$axios.$patch(`/api/v1/posts/${id}`, data)
} catch (error) {
console.log(error)
}
},
},
}
</script>
and my API
router.patch('/posts/:id', async (req, res) => {
try {
const banned = await Post.findByIdAndUpdate(req.params.id, req.body)
res.status(201).json({ banned })
} catch (err) {
res.json({
message: err.message,
})
}
})
I don't know why take() options not get correct number as I expect.
Example ,I type take:2 but it just get one product, but when I remove relations it work normal.It is so strange with me,Am I missing something?
My code
async getProducts(#Arg("searchOptions") searchOptions : SearchOptionsInput): Promise<ProductResponse> {
try {
const {skip,type} = searchOptions
const findOptions: { [key: string]: any } = {
skip,
take: 2,
relations: ["prices"],
};
switch (type) {
case "PRICE_DESC":
findOptions.order = {
prices: {
price: "DESC"
}
}
break;
default:
findOptions.order = {
createdAt:"DESC"
}
break;
}
const products = await Product.find(findOptions);
return {
code: 200,
success: true,
products,
};
} catch (error) {
return {
code: 500,
success: false,
message: `Server error:${error.message}`,
};
}
}
My query
query GetProducts{
getProducts(searchOptions:{
skip:0,
type:"PRICE_DESC"
}){
code
success
products{
id
prices{
price
}
}
}
}
I am trying to integrate Pusher with the Wix HTTP Functions
For example:
A GET request is made to the Wix site ( path: '/findItems' ). After the request is made, I want to check for new insertion of items in the database. This, I found, I could do with the afterInsert hook. When the hook is hooked, I want to trigger the Pusher.
This is the code I am currently using http-functions.js:
import { ok, created, notFound, serverError } from 'wix-http-functions';
import wixData from 'wix-data';
import Pusher from "pusher";
const pusher = new Pusher({
appId: "xxxxx",
key: "xxxxxxxxxxxxxxx",
secret: "xxxxxxxxxxxx",
cluster: "xxxx",
useTLS: true
});
export function get_findItems(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
return wixData.query("users")
.eq("firstName", request.path[0])
.eq("lastName", request.path[1])
.find()
.then((results) => {
if (results.items.length > 0) {
options.body = {
"items": results.items
};
return ok(options);
}
options.body = {
"error": `'${request.path[0]} ${request.path[1]}' was not found`
};
return notFound(options);
})
.catch((error) => {
options.body = {
"error": error
};
return serverError(options);
});
}
export function post_newItem(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
return request.body.text()
.then( (body) => {
return wixData.insert("users", JSON.parse(body));
} )
.then( (results) => {
options.body = {
"inserted": results
};
return created(options);
} )
.catch( (error) => {
options.body = {
"error": error
};
return serverError(options);
} );
}
export function users_afterInsert(item, context) {
let hookContext = context;
pusher.trigger("channel", "action", {
firstName: item.firstName,
lastName: item.lastName
});
return item;
}
But unfortunately, Pusher does not get triggered. After Debugging, I found that the Pusher package is installed and working but not triggering only in the afterInsert hook!
Any help is greatly appreciated!
Thanks !
The code for the afterInsert hook needs to be in a backend file named data.js, not in the http-functions.js file as you have it now.
I'm trying to build a React app where users can save specific things under their ID.
I'm using nodeJS with React and auth0 for authentication.
I'm trying to access a property on the this.props.auth object and find if that property exists in my db so if there's a match something can be saved under the user's ID.
However I'm not able to access this.props.auth.id as shown in the code below but I can access this.props.auth
Any pointers?
.
.
.
Auth.js
import history from '../../history';
import auth0 from 'auth0-js';
import { AUTH0_CONFIG } from '../../auth0';
import API from "../../utils/API"
export default class Auth {
accessToken;
idToken;
expiresAt;
userProfile;
userImage;
name;
id;
auth0 = new auth0.WebAuth({
domain: AUTH0_CONFIG.domain,
clientID: AUTH0_CONFIG.clientId,
redirectUri: AUTH0_CONFIG.callbackUrl,
responseType: 'token id_token',
scope: 'openid profile'
})
constructor() {
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.handleAuthentication = this.handleAuthentication.bind(this);
this.isAuthenticated = this.isAuthenticated.bind(this);
this.getAccessToken = this.getAccessToken.bind(this);
this.getIdToken = this.getIdToken.bind(this);
this.renewSession = this.renewSession.bind(this);
this.userInfo = this.userInfo.bind(this)
}
login() {
this.auth0.authorize();
}
handleAuthentication() {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult);
API.saveUser(authResult.idTokenPayload);
history.replace('/')
} else if (err) {
history.replace('/');
console.log(err);
alert(`Error: ${err.error}. Check the console for further details.`);
}
});
}
getAccessToken() {
return this.accessToken;
}
getIdToken() {
return this.idToken;
}
userInfo() {
return this.userProfile
}
setSession(authResult) {
// Set isLoggedIn flag in localStorage
localStorage.setItem('isLoggedIn', 'true');
console.log(authResult);
let expiresAt = (authResult.expiresIn * 1000) + new Date().getTime();
this.accessToken = authResult.accessToken
this.idToken = authResult.idToken;
this.expiresAt = expiresAt;
this.userImage = authResult.idTokenPayload.picture;
this.name = authResult.idTokenPayload.name.split(' ', 1);
this.id = authResult.idTokenPayload.nickname;
// navigate to the home route
history.replace('/');
}
renewSession() {
this.auth0.checkSession({}, (err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult)
console.log('authresult', authResult);
} else if (err) {
this.logout();
console.log(err);
alert(`Could not get a new token (${err.error}: ${err.error_description}).`);
}
});
}
logout() {
// Remove tokens and expiry time
this.accessToken = null;
this.idToken = null;
this.expiresAt = 0;
// Remove isLoggedIn flag from localStorage
localStorage.removeItem('isLoggedIn');
// navigate to the home route
history.replace('/');
}
isAuthenticated() {
// Check whether the current time is past the
// access token's expiry time
let expiresAt = this.expiresAt;
return new Date().getTime() < expiresAt;
}
}
Home.js
class Home extends Component {
constructor(props) {
super(props)
console.log(this.props); // can access this
console.log(this.props.auth.id); // this shows undefined
this.state = {
news: [],
summary:[],
summaryUrl: '',
userID: '',
user: '', //
pageLoading: true,
gistLoading: true
}
// console.log(this.state);
}
goTo(route) {
// console.log(history, route);
this.props.history.replace(`/${route}`)
}
login() {
this.props.auth.login();
}
logout() {
this.props.auth.logout();
}
// API call to display trending news
componentDidMount() {
API.getArticles()
.then(res => {
this.setState({
news: res.data,
pageLoading: false,
// user: this.props.auth.id
})
// console.log(this.state);
});
API.getSavedUsers()
.then((res) => {
console.log();
res.data.forEach((el) => {
console.log(this.props.auth.id); // shows undefined
if(el.name === this.props.auth.id){
this.setState({
userID: el.authID
})
} else {
console.log('notfound');
}
})
console.log(this.state);
})
const { renewSession } = this.props.auth;
if (localStorage.getItem('isLoggedIn') === 'true') {
renewSession();
}
}
I may be wrong but from the snapshot the data-type of auth property is Auth which is an object but if you look at it, match, location etc are all shown as {…} that symbolises its an object and hence we fetch the properties using dot. I would suggest parsing the auth first and then accessing the inner properties as follows:
const auth = JSON.parse(this.props.auth);
console.log(auth.id);
Could you try this for once.
I have an app where you can create many events, and I have created an API with express and node JS. In the react-native projet, I use Axios to fetch with API. But I have this weird error in my terminal :
(node:59293) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): RangeError: Invalid status code: 0
(node:59293) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
When I try to create an event, and in my browser console I have this :
Error: Network Error
at createError (createError.js:15)
at XMLHttpRequest.handleError (xhr.js:87)
at XMLHttpRequest.dispatchEvent (event-target.js:172)
at XMLHttpRequest.setReadyState (XMLHttpRequest.js:542)
at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:378)
at XMLHttpRequest.js:482
at RCTDeviceEventEmitter.emit (EventEmitter.js:181)
at MessageQueue.__callFunction (MessageQueue.js:242)
at MessageQueue.js:108
at guard (MessageQueue.js:46)
I paste my code here, maybe I'm wrong somewhere,
BACK END PART
import Event from './model';
export const createEvent = async (req, res) => {
const { title, description } = req.body;
const newEvent = new Event({ title, description });
try {
return res.status(201).json({ event: await newEvent.save() });
} catch(e) {
return res.status(e.status).json({ error: true, message: 'Error with event' });
}
};
export const getAllEvents = async (req, res) => {
try {
return res.status(200).json({ events: await Event.find({} )});
} catch(e) {
return res.status(e.status).json({ error: true, message: 'Error with all events' });
}
};
FRONT-END PART
api.js
import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000/api';
class EventApi {
constructor() {
this.path = '/events';
}
async fetchEvents() {
try {
const { data } = await axios.get(this.path);
return data.events;
} catch (e) {
console.log(e);
}
}
async createEventPost(args) {
// console.log('nous entrons dans le cadre de la création dun evenement');
try {
console.log('nous tryons');
const res = await axios.post(`${this.path}/new`, { ...args });
console.log(res);
console.log('hello world', args);
return res;
} catch (e) {
console.log(e);
console.log('lol');
}
}
}
export {
EventApi
};
CreateScreen.js
import React, { Component } from 'react';
import { View } from 'react-native';
import { connect } from 'react-redux';
import DateTimePicker from 'react-native-modal-datetime-picker';
import moment from 'moment';
import { Ionicons } from '#expo/vector-icons';
import { createEvent } from './actions';
import { LoadingScreen } from '../../common';
import Colors from '../../../constants/colors';
import styles from './styles/CreateScreen';
import CreateEventsForm from './components/CreateEventsForm';
#connect(
state => ({
event: state.createEvent
}),
{ createEvent }
)
export default class CreateScreen extends Component {
static navigationOptions = {
title: 'Créer un événement',
header: {
style: {
backgroundColor: Colors.whiteColor
},
titleStyle: {
color: Colors.redParty
}
},
tabBar: {
icon: ({ tintColor }) => (
<Ionicons name="ios-create" size={25} color={tintColor} />
)
}
}
state = {
isDateTimePickerVisible: false,
date: moment()
}
_showDateTimePicker = () => this.setState({ isDateTimePickerVisible: true })
_handleDateTimePicker = () => this.setState({ isDateTimePickerVisible: false })
_handleDatePicked = date => {
this.setState({ date });
this._handleDateTimePicker();
}
_checkTitle() {
const { date } = this.state;
if (date > moment()) {
return moment(date).format('MMMM Do YYYY, h:mm.ss a');
}
return 'Choisir une date';
}
_checkNotEmpty() {
const { date } = this.state;
if (date > moment()) {
return false;
}
return true;
}
_createEvent = async values => {
await this.props.createEvent(values);
this.props.navigation.goBack();
}
render() {
const { event } = this.props;
if (event.isLoading) {
return (
<View style={styles.root}>
<LoadingScreen />
</View>
);
} else if (event.error.on) {
return (
<View>
<Text>
{event.error.message}
</Text>
</View>
);
}
return (
<View style={styles.root}>
<CreateEventsForm
createEvent={this._createEvent}
showDateTimePicker={this._showDateTimePicker}
checkTitle={this._checkTitle()}
/>
<DateTimePicker
isVisible={this.state.isDateTimePickerVisible}
onConfirm={this._handleDatePicked}
onCancel={this._handleDateTimePicker}
mode="datetime"
/>
</View>
);
}
}
acion.js
import { EventApi } from '../../../constants/api';
import { fetchMyEvents } from '../home/actions';
const eventApi = new EventApi();
export const CREATE_EVENT = 'CREATE_EVENT';
export const CREATE_EVENT_SUCCESS = 'CREATE_EVENT_SUCCESS';
export const CREATE_EVENT_ERROR = 'CREATE_EVENT_ERROR';
export const createEvent = args => async dispatch => {
dispatch({ type: CREATE_EVENT });
try {
await eventApi.createEventPost(args);
dispatch({ type: CREATE_EVENT_SUCCESS });
} catch (e) {
return dispatch({ type: CREATE_EVENT_ERROR });
}
return await dispatch(fetchMyEvents());
};
reducer.js
import { CREATE_EVENT, CREATE_EVENT_ERROR, CREATE_EVENT_SUCCESS } from './actions';
const INITIAL_STATE = {
error: {
on: false,
message: null
},
isLoading: false
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case CREATE_EVENT:
return {
...INITIAL_STATE,
isLoading: true
};
case CREATE_EVENT_SUCCESS:
return {
...INITIAL_STATE,
isLoading: false
};
case CREATE_EVENT_ERROR:
return {
error: {
on: true,
message: 'Error happened'
},
isLoading: false
};
default:
return state;
}
};
Don't hesitate to ask if you need more code (for example the CreateEventsForm)
Thank you !
It looks like the original error is being swallowed. One solution I found for a similar problem seems to be to drop the version of react-native - https://github.com/mzabriskie/axios/issues/640, but a better approach would to be to discover the original error and then you should be able to address that - https://www.webkj.com/react-native/javascript-error-unhandled-promise-rejection-warning :