How to communicate between microservices using event bus? - vue.js

I'm trying to send data from one microservice to another through event bus. But still as a result I'm getting an empty data, I don't get what I'm doing wrong, please help.
Trying to send data:
app.get ('/products', async (req , res) => {
let db = await connect();
let cursor = await db.collection('posts').find({});
let doc = await cursor.toArray();
res.json(doc);
if (doc.insertedCount == 1) {
res.send({
status: 'success',
id: results.insertedId,
});
}
else {
res.send({
status: 'fail',
});
}
axios.get('http://localhost:4205/events', {
type: 'Success',
data: {
_id: mongo.ObjectID(id),
doc,
postId: req.params.id,
}
})
});
Event bus:
app.get('/events', async (req, res) => {
const event = req.body;
res.json(event);
axios.get('http://localhost:4202/events', event)
res.send({status:'OK'})
})
Microservice where I want to fetch the data:
app.get('/events', async (req, res) => {
res.send(req.body)
});

First:
app.get('/products', async (req, res) => {
try {
const db = await connect();
const cursor = await db.collection('posts').find({});
const doc = await cursor.toArray();
/* Below are weird code
res.json(doc);
if (doc.insertedCount == 1) {
res.send({
status: 'success',
id: results.insertedId,
});
} else {
res.send({
status: 'fail',
});
}
*/
axios.post('http://localhost:4205/events', {
type: 'Success',
data: {
id: mongo.ObjectID(id),
doc,
postId: req.params.id,
},
});
return res.status(200).send();
} catch (error) {
// Here catch and do something with errors;
console.log(error);
}
});
Second:
app.post('/events', async (req, res) => {
try {
const event = req.body;
console.log(event);
// What's mean next line ?
// res.json(event);
const response = await axios.post('http://localhost:4202/events', event);
console.log(response);
return res.status(200).json({ status: 'OK' });
} catch (error) {
console.log(error);
}
});
Last
app.post('/events', async (req, res) => {
try {
console.log(req.body);
return res.status(200).json(req.body);
} catch (error) {
console.log(error);
}
});

Related

I changed nothing to my code and now I have " TypeError: Cannot destructure property 'type' of 'vnode' as it is null. " when I launch my web app

I have a web application which is linked to an API. Usually I launch the API and it works. And now, for no reason ( I change nothing in my code and in the API ), it does not work anymore and I can a ton of error like the one I shared on my web application. What can I do ?
`
at callWithErrorHandling (vue.runtime.esm-bundler.js?ebac:123)
at setupStatefulComponent (vue.runtime.esm-bundler.js?ebac:1242)
at setupComponent (vue.runtime.esm-bundler.js?ebac:1238)
at mountComponent (vue.runtime.esm-bundler.js?ebac:838)
at processComponent (vue.runtime.esm-bundler.js?ebac:834)
at patch (vue.runtime.esm-bundler.js?ebac:755)
at ReactiveEffect.componentUpdateFn [as fn] (vue.runtime.esm-bundler.js?ebac:856)
at ReactiveEffect.run (vue.runtime.esm-bundler.js?ebac:67)
at setupRenderEffect (vue.runtime.esm-bundler.js?ebac:881)
`
I tried to relaunch the web application but same problem.
I also have a really long answer so I will try to shorten it but it can come from the store in src/stores/yourstore.js
First you will have to import what you need and do it like if it was a state
import { defineStore } from "pinia";
export const useGlobalStateStore = defineStore("global", {
state: () => ({
globalSell: 0,
whateverarray: [...],
}),
Then, you have the getter and actions ( not getter and setter be carful )
getters: {
doubleCount(state) {
return state.globalSell * 2;
},
},
actions: {
incrementGlobalSell() {
this.globalSell++;
},
deleteCategory(id) {
this.categories = this.categories.filter((element) => {
return element.id != id;
});
},
And if you want to import it on you file, it will be first an import pn indexPage.js for example or whatever you want
<script>
-> import {useGlobalStateStore} from "stores/globalState";
import NavComponent from "components/NavComponent";
In the data you get the store
data() {
return {
-> store : useGlobalStateStore(),
email: "",
And to use it it will be
this.store.whatyouwant = whatyouwanttostore
Now for the potential API problem, Make sure to do the good configuration.
this is for the db.config.js in app/config/
module.exports = {
HOST:"sql12.freemysqlhosting.net",
USER:"user",
PASSWORD:"pass",
DB:"nameOfDB"
}
Other configuration you may need is the token config but it's a little bit complicated so no problem with it, tell me if you need it later.
Example of my file from customer.controller.js
const Customer = require("../models/customer.model.js");
const getAllCustomer = (req, res) => {
Customer.getAllRecords((err, data) => {
if (err) {
res.status(500).send({
message: err.message || "Some error occured while
retriveing data.",
});
} else res.send(data);
});
};
const createNewCustomer = (req, res) => {
if (!req.body) {
res.status(400).send({
message: "Content can not be empty.",
});
}
const customerObj = new Customer({
name: req.body.name,
mail: req.body.mail,
password: req.body.password,
address: req.body.address,
postCode: req.body.postCode,
city: req.body.city
});
Customer.create(customerObj, (err, data) => {
console.log(req.body)
if (err) {
res.status(500).send({
message: err.message || "Some error occured while
creating.",
});
} else {
res.send(data);
}
});
};
const updateCustomer = (req, res) =>{
if(!req.body){
res.status(400).send({ message: "Content can not be
empty."});
}
const data = {
name: req.body.name,
mail: req.body.mail,
password: req.body.password,
address: req.body.address,
postCode: req.body.postCode,
city: req.body.city
};
Customer.updateByID(req.params.id, data, (err, result)=>{
if(err){
if(err.kind == "not_found"){
res.status(401).send({
message: "Not found Customer id: " +
req.params.id
});
} else{
res.status(500).send({
message: "Error update Customer id: " +
req.params.id
});
}
} else res.send(result);
});
};
const deleteCustomer = (req, res) =>{
Customer.delete(req.params.id, (err, result)=>{
if(err){
if(err.kind == "not_found"){
res.status(401).send({
message: "Not found Customer id: " +
req.params.id
});
}else{
res.status(500).send({
message: "Error delete Customer id: " +
req.params.id
});
}
}
else res.send(result);
});
};
const loginCustomer = (req, res) => {
if (!req.body) {
res.status(400).send({
message: "Content can not be empty.",
});
}
const account = new Customer({
mail: req.body.mail,
password: req.body.password
});
Customer.login(account, (err, data)=>{
if(err){
if(err.kind == "not_found"){
res.status(401).send({
message: "Not found " + req.body.mail
});
} else if (err.kind == "invalid_pass"){
res.status(401).send({
message: "Invalid Password"
});
} else{
res.status(500).send({
message: "Error retriveing " + req.body.mail
});
}
}else res.send(data);
});
};
module.exports = {
getAllCustomer,
createNewCustomer,
updateCustomer,
deleteCustomer,
loginCustomer
};
The problem you have could come from the route also in src/router/routes.js
const routes = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('pages/IndexPage.vue') },
{ path: 'signin', component: () => import('pages/SigninPage.vue')
},
{ path: 'signup', component: () => import('pages/SignupPage.vue')
},
]
},
{
path: '/:catchAll(.*)*',
component: () => import('pages/ErrorNotFound.vue')
}
]
export default routes
This error could come from the route, try this an give me update!
And if we follow this priciple, the API route would be
module.exports = (app) => {
const customer_controller =
require("../controllers/customer.controller")
var router = require("express").Router();
router.post("/add", customer_controller.createNewCustomer);
router.get("/all", customer_controller.getAllCustomer);
router.put("/:id", customer_controller.updateCustomer);
router.delete("/:id", customer_controller.deleteCustomer);
router.post("/login", customer_controller.loginCustomer);
app.use("/api/customer", router);
};
Maybe there is a problem with the axios.js file in src/boot/ folder
import { boot } from 'quasar/wrappers'
import axios from 'axios'
// example: const RESTURL = "http://172.26.117.16:3000/api"
const RESTURL = "http://localhost:3000/api"
const api = axios.create({
baseURL: RESTURL,
headers:{ "Content-type" : "application/json" }
})
export default boot(({ app }) => {
app.config.globalProperties.$axios = axios
app.config.globalProperties.$api = api
app.config.globalProperties.$RESTURL = RESTURL
})
export { api, RESTURL }
You can try this !
And to use you new formatted axios in javascript page
this.$api.post("/customer/login", data)
.then(res => {
if (res.status == 200){
this.errorMessage = ""
this.store.loggedUser = res.data
this.$router.push('/')
}
})
.catch((err) => {
this.errorMessage = "Wrong Mail / Password"
})
Example of my customer.model.js
const sql = require("./db");
//Constructor
const Customer = function (customer) {
this.name = customer.name;
this.mail = customer.mail;
this.password = customer.password;
this.address = customer.address;
this.postCode = customer.postCode;
this.city = customer.city;
};
Customer.getAllRecords = (result) => {
sql.query("SELECT * FROM Customer", (err, res) => {
if (err) {
console.log("Query error: " + err);
result(err, null);
return;
}
result(null, res);
});
};
Customer.create = ( newCustomer, result ) => {
sql.query("INSERT INTO Customer SET ?", newCustomer, (err, res)
=> {
if (err) {
console.log("Query error: " + err);
result(err, null);
return;
}
console.log("Created Customer: ", {
id: res.insertId,
...newCustomer
});
result(null, {
id: res.insertId,
...newCustomer
});
})
}
Customer.updateByID = (id, data, result) => {
sql.query(
"UPDATE Customer SET name=?, mail=?, password=?, address=?,
postCode=?, city=? WHERE id=?",
[data.name, data.mail, data.password, data.address,
data.postCode, data.city, id],
(err, res) => {
if (err) {
console.log("Query error: " + err);
result(err, null);
return;
}
if (res.affectedRows == 0) {
//this id not found
result({ kind: "not_found" }, null);
return;
}
console.log("Updated Customer: ", { id: id, ...data });
result(null, { id: id, ...data });
}
);
};
Customer.delete = ( id, result ) => {
sql.query("DELETE FROM Customer WHERE id = ?", id, (err, res)
=> {
if (err) {
console.log("Query error: " + err);
result(err, null);
return;
} if(res.affectedRows == 0){
result({kind: "not_found"}, null)
return;
}
console.log("Deleted Customer id: ", id)
result(null, {id: id})
});
}
Customer.login = (account, result) => {
sql.query(
"SELECT * FROM Customer WHERE mail = ?", account.mail,
(err, res) => {
if (err) {
console.log("Query error: " + err);
result(err, null);
return;
}
if (res.length) {
const validPassword = account.password ==
res[0].password
if (validPassword) {
result(null, res[0]);
return;
} else {
console.log("Password invalid.");
result({ kind: "invalid_pass" }, null);
return;
}
}
result({ kind: "not_found" }, null);
}
);
};
module.exports = Customer
I had the same problem and I solved it.
You can try to relaunch the API every 15min. It works at the second time for me. But I don't know why.

No 'Access-Control-Allow-Origin' header is present on the requested resource (MERN)

This error is never ending, I keep getting it and it's been days I've been trying to find a solution for this annoying error.
Here is what happens when I try to log in.
My app works perfectly fine in localhost but there are alot of issue when I uploaded it to heroku and it is really annoying.
Im using
Axios.defaults.withCredentials = true;
code on my every front end.
My backend
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose")
const app = express();
const bcrypt = require("bcryptjs")
const saltRounds = 10;
const bodyParser = require("body-parser")
const cookieParser = require("cookie-parser")
const session = require("express-session")
const voterModel = require('./modules/voters.js')
const presidentModel = require('./modules/president.js')
const viceModel = require('./modules/vice.js')
const treasurerModel = require('./modules/treasurer.js')
var MongoDBStore = require('connect-mongodb-session')(session);
app.use(express.json());
const corsOptions = {
origin: 'https://incomparable-speculoos-abdd5f.netlify.app',
//update: or "origin: true," if you don't wanna add a specific one
credentials: true,
};
app.use(cors(corsOptions));
app.options('*', cors());
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }))
mongoose.connect("hidden",
{
useNewUrlParser: true,
useUnifiedTopology: true
}
)
var store = new MongoDBStore({
uri: 'hidden',
collection: 'sessions'
});
// Catch errors
store.on('error', function(error) {
console.log(error);
});
app.use(session({
secret: "hidden",
resave: false,
store: store,
saveUninitialized: false,
cookie: {
maxAge: 1000 * 60 * 60 * 24
}
}))
app.post('/login', async (req, res) => {
const email = req.body.email;
const password = req.body.password;
voterModel.find({email: email}, {"email":1}, async (err, result) => {
if (err) {
console.log(err)
} else {
if(result.length > 0) {
const user = await voterModel.findOne({email: email})
const pass = await user.comparePassword(password)
if (pass) {
req.session.user = user
} else {
console.log("NOT LOGGED IN")
res.send({ message: 'Invalid email or password!'})
}
} else {
console.log("NOT LOGGED IN")
res.send({ message: 'Invalid email or password!'})
}
}
})
})
app.post('/register', async (req, res) => {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
// HASING PASSWORD
bcrypt.hash(password, saltRounds, async (err, hash) => {
if (err) {
console.log(err)
}
// INSERTING VALUES
const voters = await voterModel({email: email, username: username, password: hash, status: false})
// CHECKS IF EMAIL IS IN USE
const isNewEmail = await voterModel.isThisEmailInUse(email)
if (!isNewEmail) return res.send({ message: 'This email is already taken!'})
// SAVES THE INSERT DATA FOR VOTERS
await voters.save()
res.send({success: true})
})
})
app.post('/voted', async (req, res) => {
// FOR UPDATING THE VOTING STATUS
const email = req.body.email
// VARIABLES FOR CHOSEN CANDIDATES OF USER
const president = req.body.president
const vice = req.body.vice
const treasurer = req.body.treasurer
// SETS THE STATUS OF VOTER TO TRUE SO HE/SHE CAN ONLY VOTE ONCE
voterModel.updateOne({email: email}, {$set : {status: true}}, (err, result) => {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
// BELOW ARE THE COMMANDS FOR INCREMENTING THE VOTE COUNT OF SELECTED CANDIDATES OF THE VOTER
presidentModel.updateOne({nickname: president}, {$inc : {votes: 1}}, (err, result) => {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
viceModel.updateOne({nickname: vice}, {$inc : {votes: 1}}, (err, result) => {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
treasurerModel.updateOne({nickname: treasurer}, {$inc : {votes: 1}}, (err, result) => {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
})
app.get('/login', (req, res) => {
if (req.session.user) {
res.send({loggedIn: true, user: req.session.user})
} else {
res.send({loggedIn: false})
}
})
app.post('/checkVote', (req, res) => {
const email = req.body.email
const num = true;
voterModel.find({ $and : [{email: email}, {status : num}]},(err, result) => {
if (err) {
console.log(err)
} else {
console.log(result)
if (result.length > 0) {
res.send( {voted: true } )
} else {
res.send( {voted: false } )
}
}
})
})
app.get("/logout", (req, res) => {
req.session.destroy(err => {
if (err) return next(err)
res.status(200).send('logged out')
})
res.status(200).send('User has been logged out');
});
const PORT = process.env.PORT || 3001
app.listen(PORT, () => {
console.log('running on port 3001')
})

Vue3 Errorhandling in Vuex , how to catch error, when you indirectly dispatch a naction?

auth(){} is to send request to the server. For, authentication ,login and signUp url is different. So I use two actions to assign the url by mode "login/signUp". then "login" and "signUp" will dispatch auth(){}
In the past, I directly put send request function fetch () in login() / signUp(). when error throw out ,I can catch it by use try {} catch{}.
Now, I want to reduct the duplicated code . The problem is , the error will be throw out by auth(), in Vue3 component, what I dispatch is not auth(), it is login() / signUp().
How can I get the error? will it be possible to pass the error through login()/signUp(),then I can get it ?
updated:
auth.vue
async setUser() {
if (this.mode === "sign up") {
if (this.emailIsValid === true && this.passwordsIsValid === true) {
const payload = {
email: this.email,
password: this.password,
};
await this.$store.dispatch("homepage/signUp", payload);
}
} else if (this.mode === "login") {
if (this.emailIsValid === true && this.passwordsIsValid === true) {
this.isLoading = true;
const payload = {
email: this.email,
password: this.password,
};
try {
await this.$store.dispatch("homepage/login", payload);
} catch (err) {
this.isLoading = false;
// console.log(err);
this.error = err.message || "something went wrong";
}
}
}
},
Vuex actions.js
async signUp (context, payload) {
context.dispatch('auth', {
...payload,
mode: 'sign up'
})
},
async login (context, payload) {
await context.dispatch('auth', {
...payload,
mode: 'login'
})
},
async auth (context, payload) {
let url = ''
if (payload.mode === 'sign up') {
url =
'https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[api key]'
} else if (payload.mode === 'login') {
url =
'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[api key]'
}
const res = await fetch(url, {
method: 'POST',
body: JSON.stringify({
email: payload.email,
password: payload.password,
returnSecureToken: true
})
})
const resData = await res.json()
if (!res.ok) {
// console.log(resData)
const error = new Error(resData.error.message || 'Try again later ')
throw error
}
}
}
just pass error the bridge action .
add another try{} catch {}
vuex actions.js
async login (context, payload) {
try {
await context.dispatch('auth', {
...payload,
mode: 'login'
})
} catch (err) {
throw err
}
}

When I call api then redux does not wait for the response from api call and calls failure case even before getting response

ApiCall.js
Here I have called my API using Axios. I have used Promise to get the response. This response is resolved afterward and redux action calls failure case before getting this response.
export const callPostApi = async (url, body) => {
console.log('url ==> ', url, ' body ===> ', body);
return new Promise((resolve, reject) => {
try {
axios.post(url, body, config).then(
(response) => {
console.log('response ==> ', response.data);
const { success, data, message } = response.data;
if (!success) {
alert(message);
}
return resolve(response.data);
},
(error) => {
console.log('error in post api', error);
return reject(error);
}
);
} catch (error) {
console.log('error', error);
}
});
};
export const callLoginApi = async (body) => {
const resp = await callPostApi(apis.LOGIN_URL, body);
return resp;
};
ActionCreator.js
export const loginLoading = () => {
return { type: types.LOGIN_LOADING };
};
export const loginSuccess = (data) => {
return {
type: types.LOGIN_SUCCESS,
payload: data,
};
};
export const loginError = (error) => {
return { type: types.LOGIN_ERROR, error };
};
action.js
I am putting here async-await. But redux is not waiting for a response.
Here I am getting resp undefined after that API call response is received as successful.
what mistake am I making?
export const login = (body) => async (dispatch) => {
dispatch(ActionCreator.loginLoading());
try {
const resp = await callLoginApi(body);
console.log('login resp ==> ', resp);
if (resp != undefined && resp != null) {
const { success = false, message = '', data } = resp;
if (success == true) {
const obj = { user: data.user, token: data.token, isLoggedIn: true };
dispatch(ActionCreator.loginSuccess(obj));
storeJSON(CONST.user, data.user);
storeString(CONST.token, data.token);
RootNavigation.navigate(SCREENS.Tab, { screen: SCREENS.Home });
} else {
dispatch(ActionCreator.loginError(message));
}
if (message != '') {
alert(message);
}
}
} catch (error) {
dispatch(ActionCreator.loginError(error));
}
};

Getting a 401 error when trying to create a new post

I am trying to create a post using an app built in react native but everytime I try creating it gives me a 401 error after I have already logged in. I assume it isn't getting a token from AsyncStorage. I need helping.
This is the ItemContext where the functionality for creating a post-
import createDataContext from "./createDataContext";
import sellerApi from "../api/seller";
import { navigate } from "../navigationRef";
const itemReducer = (state, action) => {
switch (action.type) {
case "fetch_items":
return action.payload;
case "create_item":
return { errorMessage: "", item: action.payload };
default:
return state;
}
};
const fetchItems = dispatch => async () => {
const response = await sellerApi.get("/api/items");
console.log(response.data);
dispatch({ type: "fetch_items", payload: response.data });
};
const createItem = dispatch => async (
title,
category,
detail,
condition,
price
) => {
try {
const response = await sellerApi.post("/api/items", {
title,
category,
detail,
condition,
price
});
//this is the other place the error might be happening i need this to save in the phone local storage
console.log(response.data);
dispatch({ type: "create_item", payload: response.data });
navigate("Home");
} catch (err) {
console.log(err);
}
};
export const { Provider, Context } = createDataContext(
itemReducer,
{ createItem, fetchItems },
[]
);
this is the AuthContext where the signin and signup functionality is located and the AsyncStorage is used. Let me know if you guys need to see the node function for Auth.
import createDataContext from "./createDataContext";
import sellerApi from "../api/seller";
import { navigate } from "../navigationRef";
const authReducer = (state, action) => {
switch (action.type) {
case "add_error":
return { ...state, errorMessage: action.payload };
case "signup":
return { errorMessage: "", token: action.payload };
case "signin":
return { errorMessage: "", token: action.payload };
case "fetch_user":
return action.payload;
case "clear_error_message":
return { ...state, errorMessage: "" };
case "signout":
return { token: null, errorMessage: "" };
default:
return state;
}
};
const tryLocalSignin = dispatch => async () => {
const token = await AsyncStorage.getItem("token");
if (token) {
dispatch({ type: "signin", payload: token });
navigate("Home");
} else {
navigate("loginFlow");
}
};
const clearErrorMessage = dispatch => {
dispatch({ type: "clear_error_message" });
};
const signup = dispatch => async ({ name, phone, email, password }) => {
try {
const response = await sellerApi.post("/api/users", {
name,
phone,
email,
password
});
//this is the other place the error might be happening i need this to save in the phone local storage
await AsyncStorage.setItem("token", response.data);
console.log(response.data);
dispatch({ type: "signup", payload: response.data.token });
navigate("Home");
} catch (err) {
dispatch({ type: "add_error", payload: "FAIL" });
}
};
const signin = dispatch => async ({ email, password }) => {
try {
const response = await sellerApi.post("/api/auth", {
email,
password
});
await AsyncStorage.setItem("token", response.data);
console.log(response.data);
dispatch({ type: "signin", payload: response.data.token });
navigate("Home");
} catch (err) {
dispatch({ type: "add_error", payload: "FAIL" });
}
};
// const fetchUser = dispatch => async () => {
// const response = await sellerApi.get("/auth");
// dispatch({ type: "fetch_user", payload: response.data });
// };
//need to get the users info to display it in the accountScreen
const signout = dispatch => async () => {
await AsyncStorage.removeItem("token");
dispatch({ type: "signout" });
navigate("loginFlow");
};
export const { Provider, Context } = createDataContext(
authReducer,
{ signup, signin, signout, tryLocalSignin },
{ token: null, errorMessage: "" }
);
This is the backend for the Auth function that makes sure the user is logged in before begin able to send a post request----
const jwt = require("jsonwebtoken");
const config = require("config");
module.exports = function (req, res, next) {
const token = req.header("x-auth-token");
if (!token) return res.status(401).send("Access denied");
try {
const decoded = jwt.verify(token, config.get("jwtPrivateKey"));
req.user = decoded;
next();
} catch (ex) {
res.status(400).send("Invalid token.");
}
}
this is where the post request for when you signup and login is pretty much similar-
router.post("/", async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (user) return res.status(400).send("User already registered.");
user = new User(_.pick(req.body, "name", "phone", "email", "password"));
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
const token = user.generateAuthToken();
res.header("x-auth-token", token).send(token);
});
PLEASE HELP
Importing Async storage like this import {AsyncStorage} from 'react-native'; has been deprecated. You can check here async storage .
Thats why i suppose the AsyncStorage is not working, try downloading this rn-community-async-storage . package first and then import AsyncStorage like
import AsyncStorage from '#react-native-community/async-storage';
hope it helps. feel free for doubts