axios GET Request constantly running - javascript

I am working on my React application and noticed an error. When I console log the code below, the GET request from my Express back end, the console log runs without stopping.
api-helper.js (REACT)
export const getAllPages = async () => {
getToken();
const resp = await api.get(`pages/`);
console.log('><><><><><><><>< return getAllPages response ><><><><><><><><',resp) //
const parsedResponse = resp.data.map((page) => ({
...page,
siteName: page.siteUniqueName?.split("-")[1],
}));
return parsedResponse;
};
pageRouter.js (express)
pageRouter.get("/", restrict, async (req, res, next) => {
try {
const { user } = req;
const pages = await Page.findAll({
where: {
userId: user.id
},
include: [
{ model: Site },
{ model: VisitRecord },
{ model: Lead }
]
});
res.json(pages);
} catch (e) {
next(e);
}
});
This would obviously be bad in production if it were making calls on a live database. How do I get this to stop this get running constantly in the background?
Update:
This is the code on the dashboard that calls the API where all pages are rendered:
Dashboard.jsx
useEffect(() => {
props.getAllPages();
}, []);
App.js
getAllUserPages = async () => {
// console.log('called here1')
const pages = await getAllPages();
if (pages) {
this.setState({
sites: pages,
});
}
};
async componentDidMount() {
// console.log('called________')
const currentUser = await getCurrentUser();
if (currentUser) {
const preservedSites = await getAllPages();
this.setState({
currentUser,
preservedSites: preservedSites.map((site) => site.siteName),
});
} else {
if (
!(
this.props.history.location.pathname.startsWith("/reset/") ||
this.props.history.location.pathname === "/" ||
matchPath(this.props.history.location.pathname, {
path: "/:userId/:siteName",
exact: false,
strict: false,
})
)
) {
this.props.history.push("/auth");
}
}
const pages = await getAllPages();
if (pages) {
this.setState({
sites: pages,
});
}
const resp = await api.get("/users");
const users = resp.data;
this.setState({
users: users,
});
}

Related

The 'refreshToken' function makes the dependencies of useEffect Hook (at line 142) change on every render

I've been trying to deploy my first React App and i cannot seem to be able to get rid of the following warning which on production stops me from doing a deployment:
Line 60:11: The 'refreshToken' function makes the dependencies of useEffect Hook (at line 142) change on every render. Move it inside the useEffect callback. Alternatively, wrap the definition of 'refreshToken' in its own useCallback() Hook react-hooks/exhaustive-deps
Is there an easy way to fix this without breaking the JWT token authentification?
AuthContext.js
import React, { useEffect, useState, useCallback } from 'react'
import { API } from "../api"
import axios from "axios"
import { isAfter, isEqual, parseISO, sub } from 'date-fns'
export const AuthContext = React.createContext(null)
export function AuthContextProvider({ children }) {
const [accessTokenExpiration, setAccessTokenExpiraton] = useState(undefined);
const getUser = () => {
return JSON.parse(localStorage.getItem('user'))
}
const isLoggedIn = () => {
return localStorage.getItem('user') !== null
}
const [user, setUser] = useState(() => {
return isLoggedIn() ? getUser() : null;
})
const [shouldGoToLogin, setShouldGoToLogin] = useState(() => {
if (!user || !user.access_token || !user.refresh_token) {
return true;
}
return false;
})
const logout = async () => {
if (!user) {
return;
}
const { access_token } = user;
localStorage.removeItem('user')
setUser(null);
return axios.post(API.auth.logout, {
headers: {
"Authorization": `Bearer ${access_token}`,
"Content-Type": "application/json"
},
withCredentials: true
});
}
const login = async (values) => {
console.log(values);
const correctedValues = { ...values, username: values.email };
return axios.post(API.auth.login, correctedValues)
.then(res => {
const data = res.data;
processApiData(data);
})
}
const processApiData = useCallback((resp) => {
let newUser = { ...user, ...resp };
delete(newUser.user); // Delete the user sub-object since we merged that directly into the top-level object
saveUser(newUser); // Save the user
const { access_token_expiration } = newUser;
if (access_token_expiration) {
console.log("have expiration", access_token_expiration);
const nextExpiration = parseISO(access_token_expiration); // Convert from ISO 8601 to a Date Object
const earlyRefreshTime = sub(nextExpiration, { minutes: 55 }); // Do an hourish early
setAccessTokenExpiraton(earlyRefreshTime); // Set the upcoming expiraton
}
}, [user])
const refreshToken = useCallback(async () => {
const user = getUser();
const redirectToLogout = () => {
localStorage.clear(); // Clear our localStorage
setShouldGoToLogin(true);
};
if (!user) { // No user
redirectToLogout();
}
console.log(API.auth.refreshToken);
const resp = await fetch(API.auth.refreshToken, {
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({'refresh': user?.refresh_token}),
method: "POST",
withCredentials: true
})
console.log("status", resp.status);
if (resp.status === 200) {
const data = await resp.json(); // Convert to JSON
console.log("refresh token data", data);
processApiData(data);
} else {
redirectToLogout();
}
}, [processApiData])
const resetPassword = async (values) => {
return axios.post(API.auth.passwordReset, values);
}
const saveUser = async (newUser) => {
localStorage.setItem('user', JSON.stringify(newUser))
setUser(newUser)
}
const signup = async (values) => {
return axios.post(API.auth.signup, values);
}
useEffect(() => {
if (!user) {
return;
}
const interval = setInterval(()=> {
if(!user){
return false;
}
if (accessTokenExpiration) {
const now = new Date(); // Get the current time
console.log(now);
console.log(accessTokenExpiration);
if (isAfter(now, accessTokenExpiration) || isEqual(now, accessTokenExpiration)) { // If we are late to the party or the stars have aligned
refreshToken(); // Refresh the token
}
} else { // We do not have an access token expiration yet
refreshToken(); // Refresh the token immediately so we get a time
}
}, 1000 * 15)
return ()=> clearInterval(interval)
}, [accessTokenExpiration, refreshToken, user])
return (
<AuthContext.Provider value={{
getUser,
isLoggedIn,
logout,
login,
resetPassword,
signup,
user,
shouldGoToLogin
}}>
{children}
</AuthContext.Provider>
)
}
Put refreshToken function directly in your useEffect hook or wrap in useCallback.

Trying to figure out how to use socket.io the correct way in a useEffect that is using an axios get request to fetch messages

So far i'm stuck on my useEffect that fetches all the current messages and renders the state accordingly. as of right now it doesn't render the new state until page is refreshed.
const Home = ({ user, logout }) => {
const history = useHistory();
const socket = useContext(SocketContext);
const [conversations, setConversations] = useState([]);
const [activeConversation, setActiveConversation] = useState(null);
const classes = useStyles();
const [isLoggedIn, setIsLoggedIn] = useState(false);
const addSearchedUsers = (users) => {
const currentUsers = {};
// make table of current users so we can lookup faster
conversations.forEach((convo) => {
currentUsers[convo.otherUser.id] = true;
});
const newState = [...conversations];
users.forEach((user) => {
// only create a fake convo if we don't already have a convo with this user
if (!currentUsers[user.id]) {
let fakeConvo = { otherUser: user, messages: [] };
newState.push(fakeConvo);
}
});
setConversations(newState);
};
const clearSearchedUsers = () => {
setConversations((prev) => prev.filter((convo) => convo.id));
};
const saveMessage = async (body) => {
const { data } = await axios.post("/api/messages", body);
return data;
};
const sendMessage = (data, body) => {
socket.emit("new-message", {
message: data.message,
recipientId: body.recipientId,
sender: data.sender,
});
};
const postMessage = async (body) => {
try {
const data = await saveMessage(body);
if (!body.conversationId) {
addNewConvo(body.recipientId, data.message);
} else {
addMessageToConversation(data);
}
sendMessage(data, body);
} catch (error) {
console.error(error);
}
};
const addNewConvo = useCallback(
(recipientId, message) => {
conversations.forEach((convo) => {
if (convo.otherUser.id === recipientId) {
convo.messages.push(message);
convo.latestMessageText = message.text;
convo.id = message.conversationId;
}
});
setConversations(conversations);
},
[setConversations, conversations],
);
const addMessageToConversation = useCallback(
(data) => {
// if sender isn't null, that means the message needs to be put in a brand new convo
const { message, sender = null } = data;
if (sender !== null) {
const newConvo = {
id: message.conversationId,
otherUser: sender,
messages: [message],
};
newConvo.latestMessageText = message.text;
setConversations((prev) => [newConvo, ...prev]);
}
conversations.forEach((convo) => {
console.log('hi', message.conversationId)
if (convo.id === message.conversationId) {
const convoCopy = { ...convo }
convoCopy.messages.push(message);
convoCopy.latestMessageText = message.text;
console.log('convo', convoCopy)
} else {
return convo
}
});
setConversations(conversations);
},
[setConversations, conversations],
);
const setActiveChat = useCallback((username) => {
setActiveConversation(username);
}, []);
const addOnlineUser = useCallback((id) => {
setConversations((prev) =>
prev.map((convo) => {
if (convo.otherUser.id === id) {
const convoCopy = { ...convo };
convoCopy.otherUser = { ...convoCopy.otherUser, online: true };
return convoCopy;
} else {
return convo;
}
}),
);
}, []);
const removeOfflineUser = useCallback((id) => {
setConversations((prev) =>
prev.map((convo) => {
if (convo.otherUser.id === id) {
const convoCopy = { ...convo };
convoCopy.otherUser = { ...convoCopy.otherUser, online: false };
return convoCopy;
} else {
return convo;
}
}),
);
}, []);
// Lifecycle
useEffect(() => {
// Socket init
socket.on("add-online-user", addOnlineUser);
socket.on("remove-offline-user", removeOfflineUser);
socket.on("new-message", addMessageToConversation);
return () => {
// before the component is destroyed
// unbind all event handlers used in this component
socket.off("add-online-user", addOnlineUser);
socket.off("remove-offline-user", removeOfflineUser);
socket.off("new-message", addMessageToConversation);
};
}, [addMessageToConversation, addOnlineUser, removeOfflineUser, socket]);
useEffect(() => {
// when fetching, prevent redirect
if (user?.isFetching) return;
if (user && user.id) {
setIsLoggedIn(true);
} else {
// If we were previously logged in, redirect to login instead of register
if (isLoggedIn) history.push("/login");
else history.push("/register");
}
}, [user, history, isLoggedIn]);
useEffect(() => {
const fetchConversations = async () => {
try {
const { data } = await axios.get("/api/conversations");
setConversations(data);
} catch (error) {
console.error(error);
}
};
if (!user.isFetching) {
fetchConversations();
}
}, [user]);
const handleLogout = async () => {
if (user && user.id) {
await logout(user.id);
}
};
return (
<>
<Button onClick={handleLogout}>Logout</Button>
<Grid container component="main" className={classes.root}>
<CssBaseline />
<SidebarContainer
conversations={conversations}
user={user}
clearSearchedUsers={clearSearchedUsers}
addSearchedUsers={addSearchedUsers}
setActiveChat={setActiveChat}
/>
<ActiveChat
activeConversation={activeConversation}
conversations={conversations}
user={user}
postMessage={postMessage}
/>
</Grid>
</>
);
};
this is the main part im working on, the project had starter code when i began and was told not to touch the backend so i know its something wrong with the front end code. i feel like im missing something important for the socket.io
import { io } from 'socket.io-client';
import React from 'react';
export const socket = io(window.location.origin);
socket.on('connect', () => {
console.log('connected to server');
});
export const SocketContext = React.createContext();
this is how i have the socket.io setup, if anyone could point me in the right direction that would be cool. I have been reading up on socket.io as much as I can but am still pretty lost on it.
Based on the assumption the backend is working properly...
const addNewConvo = useCallback(
(recipientId, message) => {
conversations.forEach((convo) => {
if (convo.otherUser.id === recipientId) {
convo.messages.push(message);
convo.latestMessageText = message.text;
convo.id = message.conversationId;
}
});
setConversations(conversations);
},
[setConversations, conversations],
);
setConversations(conversations);
This is an incorrect way to set a state using the state's variable, and such it wont do anything. Likely why your code wont change until refresh.
Suggested fix:
const addNewConvo = useCallback(
(recipientId, message) => {
setConversations(previousState => previousState.map(convo => {
if (convo.otherUser.id === recipientId) {
convo.messages.push(message)
convo.latestMessageText = message.text;
convo.id = message.conversationId;
return convo
}
return convo
}))
},
[setConversations, conversations],
);
note: even above could be done more efficiently since I made a deep copy of messages

Why is my UseEffect for making requests to Spotify API giving an error 429?

I am currently making a Spotify clone which gives user a preview of the song. The problem occurs when I am making many different api requests. When there are more than one requests on the page, it throws a 429 error(making too many requests at once).
Please read through the whole question as I have mentioned the steps I have taken to fix this below.
Profile.js
const { api, refreshableCall } = useSpotify()
const [error, setError] = useState(null)
const [userName, setUserName] = useState("")
const [userFollowers, setUserFollowers] = useState("")
const [userImage, setUserImage] = useState([])
const [userLink, setUserLink] = useState("")
const [userId, setUserId] = useState("")
const [userFollowing, setUserFollowing] = useState("")
const [userTopArtists, setUserTopArtists] = useState([])
const [userTopSongs, setUserTopSongs] = useState([])
useEffect(() => {
let disposed = false
refreshableCall(() => api.getMyTopTracks({
limit: 10,
time_range: "long_term"
}))
.then((res) => {
if (disposed) return
setUserTopSongs(res.body.items)
setError(null)
})
.catch((err) => {
if (disposed) return
setUserTopSongs([])
setError(err)
});
return () => disposed = true
})
useEffect(() => {
let disposed = false
refreshableCall(() => api.getMe())
.then((res) => {
if (disposed) return
var data = res.body
setUserName(data.display_name)
setUserImage(data.images)
setUserFollowers(data.followers["total"])
setUserLink(data.external_urls.spotify)
setUserId(data.id)
setError(null)
})
.catch((err) => {
if (disposed) return
setUserName("")
setUserImage([])
setUserFollowers("")
setUserLink("")
setUserId("")
setError(err)
});
return () => disposed = true
})
useEffect(() => {
let disposed = false
refreshableCall(() => api.getFollowedArtists())
.then((res) => {
if (disposed) return
var data = res.body
var artists = data.artists
setUserFollowing(artists.total)
})
.catch((err) => {
if (disposed) return
setUserFollowing([])
setError(err)
});
return () => disposed = true
})
useEffect(() => {
let disposed = false
refreshableCall(() => api.getMyTopArtists({
limit: 10,
time_range: "long_term"
}))
.then((res) => {
if (disposed) return
var data = res.body
var artists = data.items
setUserTopArtists(artists)
setError(null)
})
.catch((err) => {
if (disposed) return
setUserTopArtists([])
setError(err)
});
return () => disposed = true
})
SpotifyContext.js
import React, { useState, useEffect, useContext } from "react"
import axios from "axios"
import SpotifyWebApi from 'spotify-web-api-node';
const spotifyApi = new SpotifyWebApi({
clientId: 1234567890,
});
export const SpotifyAuthContext = React.createContext({
exchangeCode: () => { throw new Error("context not loaded") },
refreshAccessToken: () => { throw new Error("context not loaded") },
hasToken: spotifyApi.getAccessToken() !== undefined,
api: spotifyApi
});
export const useSpotify = () => useContext(SpotifyAuthContext);
function setStoredJSON(id, obj) {
localStorage.setItem(id, JSON.stringify(obj));
}
function getStoredJSON(id, fallbackValue = null) {
const storedValue = localStorage.getItem(id);
return storedValue === null
? fallbackValue
: JSON.parse(storedValue);
}
export function SpotifyAuthContextProvider({ children }) {
const [tokenInfo, setTokenInfo] = useState(() => getStoredJSON('myApp:spotify', null))
const hasToken = tokenInfo !== null
useEffect(() => {
if (tokenInfo === null) return;
// attach tokens to `SpotifyWebApi` instance
spotifyApi.setCredentials({
accessToken: tokenInfo.accessToken,
refreshToken: tokenInfo.refreshToken,
})
// persist tokens
setStoredJSON('myApp:spotify', tokenInfo)
}, [tokenInfo])
function exchangeCode(code) {
return axios
.post("http://localhost:3001/login", {
code
})
.then(res => {
// TODO: Confirm whether response contains `accessToken` or `access_token`
const { accessToken, refreshToken, expiresIn } = res.data;
// store expiry time instead of expires in
setTokenInfo({
accessToken,
refreshToken,
expiresAt: Date.now() + (expiresIn * 1000)
});
})
}
function refreshAccessToken() {
const refreshToken = tokenInfo.refreshToken;
return axios
.post("http://localhost:3001/refresh", {
refreshToken
})
.then(res => {
const refreshedTokenInfo = {
accessToken: res.data.accessToken,
// some refreshes may include a new refresh token!
refreshToken: res.data.refreshToken || tokenInfo.refreshToken,
// store expiry time instead of expires in
expiresAt: Date.now() + (res.data.expiresIn * 1000)
}
setTokenInfo(refreshedTokenInfo)
// attach tokens to `SpotifyWebApi` instance
spotifyApi.setCredentials({
accessToken: refreshedTokenInfo.accessToken,
refreshToken: refreshedTokenInfo.refreshToken,
})
return refreshedTokenInfo
})
}
async function refreshableCall(callApiFunc) {
if (Date.now() > tokenInfo.expiresAt)
await refreshAccessToken();
try {
return await callApiFunc()
} catch (err) {
if (err.name !== "WebapiAuthenticationError")
throw err; // rethrow irrelevant errors
}
// if here, has an authentication error, try refreshing now
return refreshAccessToken()
.then(callApiFunc)
}
return (
<SpotifyAuthContext.Provider value={{
api: spotifyApi,
exchangeCode,
hasToken,
refreshableCall,
refreshAccessToken
}}>
{children}
</SpotifyAuthContext.Provider>
)
}
Errors
Without the dependency, it keeps cycling and firing off requests, likely hundreds per second. (Error 429)
With the dependency, it seems the Access Token is being ignored or sidestepped. (Error: WebApiAuthentication - No token provided)
What I have tried to do ?
I tried to implement all the requests in a single useEffect, still getting the errors.
Calling useEffect with dependency array and without.
Link to the Github Repo
https://github.com/amoghkapoor/spotify-clone
status 429 means you have made too many calls in a specific time window.
you are therefore banned for this specific time window.
try waiting a bit before retrying.
did you try :
useEffect(..., [])
this guaranties it will be run only once.
None of your useEffect calls are using a dependency array, remember if useEffect is called without any dependencies it goes into an infinite loop. Either find what dependency or state change should re-run the useEffect hook and include it in the dependency array:
useEffect(() => { /* your logic */ }, [dependencies])
or if there are no dependencies simply fire it once the component mounts:
useEffect(() => { /* your logic */ }, [])

why componentdidmount called two times

I have React Component in componentDidMount fetch data from the server. The issue is componentDidMount called twice also the API called twice. I have a view increment API like youtube video views increment twice in the database because of twice API calling.
class SingleVideoPlay extends React.Component {
constructor(props) {
super(props);
this.player = React.createRef();
}
state = {
autoPlay: true,
relatedVideos: [],
video: null,
user: null,
comments: [],
commentInput: {
value: '',
touch: false,
error: false
},
following: false,
tab: 'comments'
};
_Mounted = false;
componentDidMount() {
this._Mounted = true;
if (this._Mounted) {
const videoId = this.props.match.params.id;
this.getVideoDetails(videoId);
}
}
componentWillUnmount() {
this._Mounted = false;
try {
clearInterval(this.state.videoInterval);
this.props.videoEditUrl('');
} catch (error) {}
}
captureVideoTime = async () => {
const { video } = this.state;
const result = await updateWatchTime({
id: video._id,
time: 1
});
if (result.status === 200) {
const updateVideo = {
...video,
secondsWatched: video.secondsWatched + 1
};
this.setState({ video: updateVideo });
}
};
videoEnded = () => {
clearInterval(this.state.videoInterval);
};
videoPause = () => {
clearInterval(this.state.videoInterval);
};
loadVideo = () => {
clearInterval(this.state.videoInterval);
};
playingVideo = () => {
const interval = setInterval(this.captureVideoTime, 1000);
this.setState({ videoInterval: interval });
};
getVideoDetails = async (videoId) => {
const video = await getVideo(videoId);
if (video.status === 200) {
let response = video.data;
if (this.props.userId)
if (response.user._id === this.props.userId._id)
this.props.videoEditUrl(`/video/edit/${response.media._id}`);
this.setState({
relatedVideos: response.videos.docs,
video: response.media,
user: response.user
});
this.checkIsFollowing();
this.updateVideoStat(response.media._id);
}
};
updateVideoStat = async (id) => videoView(id);
checkIsFollowing = async () => {
const { userId } = this.props;
const { video } = this.state;
if (userId && video) {
const response = await isFollow({
follower: userId._id,
following: video._id
});
if (response) {
this.setState({ following: response.following });
}
}
};
addOrRemoveFollowing = async () => {
this.checkIsFollowing();
const { following, video } = this.state;
const { userId } = this.props;
if (userId) {
if (following) {
const response = await removeFollow({
follower: userId._id,
following: video._id
});
this.setState({ following: false });
} else {
const response = await addFollow({
follower: userId._id,
following: video._id
});
this.setState({ following: true });
}
}
};
submitCommentHandler = async (event) => {
const { userId } = this.props;
event.preventDefault();
if (userId) {
const result = await saveComment({
mediaId: this.state.video._id,
parentId: '0',
userID: userId._id,
userName: userId.username,
comment: this.state.commentInput.value
});
console.log(result);
if (result.status === 200) {
this.getVideoComments();
this.setState({ commentInput: { value: '', touch: false, error: false } });
}
}
};
render() {
const { autoPlay, relatedVideos, video, user, comments, commentInput, following, tab } = this.state;
const { userId } = this.props;
return (
<div className="container-fluid">
some coponents
</div>
);
}
}
const mapStateToProps = (state) => ({
userId: state.auth.user
});
export default connect(mapStateToProps, { videoEditUrl })(SingleVideoPlay);
I don't know why componentDidMount called two times alse it shows memmory lecage issue.
How to Fix it.
Multiple componentDidMount calls may be caused by using <React.StrictMode> around your component. After removing it double calls are gone.
This is intended behavior to help detect unexpected side effects. You can read more about it in the docs. It happens only in development environment, while in production componentDidMount is called only once even with <React.StrictMode>.
This was tested with React 18.1.0
I think the issue exists on the parent component that used SingleVideoPlay component. Probably that parent component caused SingleVideoPlay component rendered more than once.
Also, there is an issue on your code.
componentDidMount() {
this._Mounted = true;
if (this._Mounted) {
const videoId = this.props.match.params.id;
this.getVideoDetails(videoId);
}
}
Here, no need to check if this._Mounted, because it will always be true.
1.Install jQuery by
npm i jquery
import $ from 'jquery'
create your function or jwuery code after the export command or put at the end of the file

Transaction numbers are only allowed on storage engines that support document-level locking - MongodbMemoryServer/Mochai/Chai/Supertest

FIXED: USER storageEngine: "wiredTiger"
I use Mocha / Chai / Supertest and Mongodb-Memory-Server to test my app. But's I received error: Transaction numbers are only allowed on storage engines that support document-level locking
In real database and test by postman, it's working well.
My code:
In database.js
const mongoose = require('mongoose')
const { MongoMemoryReplSet } = require('mongodb-memory-server')
mongoose.set('useFindAndModify', false);
const connect = async () => {
try {
let url = process.env.MONGO_URL
let options = {
//Something
}
if (process.env.NODE_ENV === 'test') {
const replSet = new MongoMemoryReplSet();
await replSet.waitUntilRunning();
const uri = await replSet.getUri();
await mongoose.connect(uri, options)
//log connected
} else {
await mongoose.connect(url, options)
//log connected
}
} catch (error) {
//error
}
}
I have two model: Company and User. I made a function to add a member to company with used transaction. My code
const addMember = async (req, res, next) => {
const { companyId } = req.params
const { userId } = req.body
const session = await mongoose.startSession()
try {
await session.withTransaction(async () => {
const [company, user] = await Promise.all([
Company.findOneAndUpdate(
//Something
).session(session),
User.findByIdAndUpdate(
//Something
).session(session)
])
//Something if... else
return res.json({
message: `Add member successfully!`,
})
})
} catch (error) {
//error
}
}
Here's router:
router.post('/:companyId/add-member',
authentication.required,
company.addMember
)
Test file:
const expect = require('chai').expect
const request = require('supertest')
const app = require('../app')
describe('POST /company/:companyId/add-member', () => {
it('OK, add member', done => {
request(app).post(`/company/${companyIdEdited}/add-member`)
.set({ "x-access-token": signedUserTokenKey })
.send({userId: memberId})
.then(res => {
console.log(res.body)
expect(res.statusCode).to.equals(200)
done()
})
.catch((error) => done(error))
})
})
And i received error: Transaction numbers are only allowed on storage engines that support document-level locking'
How can I fix this?
Add retryWrites=false to your database uri. Example below:
mongodb://xx:xx#xyz.com:PORT,zz.com:33427/database-name?replicaSet=rs-xx&ssl=true&retryWrites=false

Categories

Resources