My project uses Angular as the frontend and Node.js as the backend with socket.io integration.
I am trying to send a post request from frontend to backend as follows:
Frontend
The button in the HTML to call the onOrder() method:
<button (click)="onOrder()" class="button">Checkout</button></div>
The method call in .ts file:
onOrder(){
console.log('pressed'); // successfully logged to console
if(this.itemsInCart.length > 0 ) {
let order: SubmitOrderModel = new SubmitOrderModel();
order.order = this.itemsInCart;
this.webSocketService.fetchOrders(order);
}
}
The SubmitOrderModel below:
export class AddToCartModel {
thumbnail?: string = '';
mealName: string = '';
addons: string[] = [];
variant?: string = '';
cost: number = 0;
quantity: number = 1;
}
export class SubmitOrderModel {
order: AddToCartModel[] = [];
}
The webSocketService methods below:
setupSocketConnection(){
this.socket.on('fetchOrders', (data: string) => {
console.log(data);
localStorage.setItem('allOrders', JSON.stringify(data[0]));
});
this.socket.on('fetchRequests', (data: string) => {
console.log(data);
localStorage.setItem('allRequests', JSON.stringify(data[0]));
StaffScreenComponent.allRequests = data;
});
}
fetchOrders(order: SubmitOrderModel) {
this.socket.emit('fetchOrders', order);
}
OnFetchOrders() {
return this.socket.fromEvent('fetchOrders');
}
Backend
and in the backend, the schema definition is as follows:
var mongoose = require('mongoose');
var menuOrderSchema = mongoose.Schema;
var AddMenuOrderSchema = new menuOrderSchema({
order: [{
thumbnail: String,
mealName: String,
addons: [String],
variant: {type: String, default: 'Standard'},
cost: Number,
quantity: Number
}],
});
var newMenuOrderSchema = mongoose.model('addMenuOrderSchema', AddMenuOrderSchema );
module.exports = newMenuOrderSchema;
And the socket configuration in the backend is below:
io.on('connection', (socket)=>{
console.log('connection')
socket.on("fetchOrders", (arg) => {
console.log('fetchOrders');
const postMenuOrderM = new addMenuOrderModel(arg);
console.log('checking')
postMenuOrderM.save().then(function(){
addMenuOrderModel.find().then(data=>{
io.emit('fetchOrders', data)
}).catch(err=>res.send(err));
});
});
socket.on('disconnect', () => console.log('disconnected'));
})
The Node.js server is not receiving any calls from the UI.
What am I doing wrong here?
Related
i created a code that Backsup/Deletes and Inserts information from the Third Party API every 24hours to update the Third party api changes daily on the database.
how can i sort the information i get from the MongoDB by which score changed the most?
API LOOKS LIKE
{
"_id": "6365e1dbde0dd3639536f4b7",
"position": 1,
"id": "105162",
"score": 2243536903,
"__v": 0
},
MY CODE
app.get('/api/TopFlops', async (req, res) => {
const topflops = await TopFlops.find({}).sort({_id: +1}).limit(5)
res.json(topflops);
})
CODE TO INSERT DATA FROM THE 3RD PARTY API TO DB
cron.schedule('59 23 * * *', async () => {
const postSchema = new mongoose.Schema({
id: {
type: Number,
required: true
},
name: {
type: String,
required: true
},
status: {
type: String,
required: false
},
});
const Post = mongoose.model('players', postSchema);
async function getPosts() {
const getPlayers = await fetch("http://localhost:3008/api/players");
const response = await getPlayers.json();
for( let i = 0;i < response.players.length; i++){
const post = new Post({
id: response.players[i]['id'],
name: response.players[i]['name'],
status: response.players[i]['status'],
});
post.save();
}
}
console.log("Table submitted successfully")
await getPosts();
});
CODE TO FETCH API
const [playerName, setPlayerName] = useState([]);
const [playerRank, setPlayerRank] = useState([]);
const [player, setPlayer] = useState([]);
const [perPage, setPerPage] = useState(10);
const [size, setSize] = useState(perPage);
const [current, setCurrent] = useState(1);
const [players, setPlayers] = useState();
const fetchData = () => {
const playerAPI = 'http://localhost:3001/api/topflops';
const playerRank = 'http://localhost:3001/api/topflops';
const getINFOPlayer = axios.get(playerAPI)
const getPlayerRank = axios.get(playerRank)
axios.all([getINFOPlayer, getPlayerRank]).then(
axios.spread((...allData) => {
const allDataPlayer = allData[0].data
const getINFOPlayerRank = allData[1].data
const newPlayer = allDataPlayer.map(name => {
const pr = getINFOPlayerRank.find(rank => name.id === rank.id)
return {
id: name.id,
name: name.name,
alliance: name.alliance,
position: pr?.position,
score: pr?.score
}
})
setPlayerName(allDataPlayer)
setPlayerRank(getINFOPlayerRank)
console.log(getINFOPlayerRank)
console.log(newPlayer)
setPlayer(newPlayer)
})
)
}
useEffect(() => {
fetchData()
}, [])
const getData = (current, pageSize) => {
// Normally you should get the data from the server
return player?.slice((current - 1) * pageSize, current * pageSize);
};
I am using Angular as frontend and NodeJS for the backend.
I have a route that saves the data received from the frontend to the database. When I execute the save() method, I get prompted the following error:
err : ValidationError: conf.0: Cast to [Boolean] failed for value "[ {
name: 'v', percentage: 2, type: false, status: true } ]" (type string)
at path "conf.0"
Below is the route that stores the data:
app.post("/api/submitTaxCollection", (req, res) => {
console.log(req.body);
const submitTaxSchema = new addTaxesSchema(req.body);
try {
submitTaxSchema.save(function (err) {
if (err) return console.log("err : " + err);
});
} catch (error) {
console.log("ERROR : " + error);
return res.send(error);
}
});
and this is the schema.ts file:
var mongoose = require("mongoose");
//Define a schema
var taxSchema = mongoose.Schema;
var AddTaxSchema = new taxSchema({
parentId: String,
conf: [
{
name: String,
percentage: Number,
type: Boolean,
status: Boolean,
},
],
});
var newTaxesSchema = mongoose.model("addTaxSchema", AddTaxSchema);
module.exports = newTaxesSchema;
In Angular, model is setup as below:
export class TaxRatesConfigurationsModel {
name: string = "";
percentage: number = 0;
type: boolean = false;
status: boolean = true;
}
export class TaxRatesModel {
parentId: string = "";
conf: TaxRatesConfigurationsModel[] = [];
}
and I am calling the API as below:
this._httpService
.post(environment.url + "/api/submitTaxCollection", request)
.subscribe((data) => {
console.log(data);
});
when I console.log(req.body);, I get the following printed to the console (Nodejs):
{
parentId: '23948923nur8cw9yicnyu',
conf: [ { name: 'v', percentage: 2, type: false, status: true } ]
}
and the error occurs in Nodejs
What is causing this weird issue?
I am trying to add a new collection, using the same ObjectId from the my users collection that was already created. But when I run the API, I get the following error Cannot read property '_id' of undefined
index.js
const express = require('express');
const authRoutes = require('./auth.routes');
const profileRoutes = require('./profile.routes');
const router = express.Router();
router.use('/auth', authRoutes);
router.use('/profile', profileRoutes);
module.exports = router;
profile.routes.js
const express = require('express');
const profileCtrl = require('../controllers/profile.controller');
const router = express.Router();
router
.route('/')
.post(profileCtrl.create)
.put(profileCtrl.update)
.get(profileCtrl.read)
.delete(profileCtrl.remove);
module.exports = router;
BaseCrudController.js
class BaseCrudController {
constructor(dataService, varName) {
if (!dataService) {
throw new Error('Data service not found', 500);
}
this.varName = varName;
this.dataService = dataService;
this.create = this.create.bind(this);
this.update = this.update.bind(this);
}
create(req, res, next) {
return this.dataService
.create(req.user, req.body)
.then((item) => res.json(item))
.catch(next);
}
update(req, res, next) {
return this.dataService
.update(req.user, req[this.varName], req.body)
.then((item) => res.json(item))
.catch(next);
}
BaseCrudService.js
const _ = require('lodash');
const mongoose = require('mongoose');
const APIError = require('../utils/api-error');
const BaseService = require('./BaseService');
class BaseCrudService extends BaseService {
constructor(
modelName,
safeFields = [],
adminFields = [],
userIdField = null,
populatedFields = [],
listPoluateField = ''
) {
super();
this.modelName = modelName;
this.safeFields = [...safeFields];
this.fields = [...safeFields];
this.adminFields = [...adminFields];
this.userIdField = userIdField;
this.populatedFields = [...populatedFields];
this.listPoluateField = listPoluateField;
this.model = mongoose.model(this.modelName);
this.create = this.create.bind(this);
this.update = this.update.bind(this);
}
_getFiedlNames(user) {
//maybe checking roles later
return [...this.safeFields];
}
create(user, data, extraData = {}) {
const Model = this.model;
const createData = {};
const fields = this._getFiedlNames(user);
if (this.userIdField) {
createData[this.userIdField] = user._id;
}
const item = new Model(
Object.assign(createData, _.pick(data, fields), extraData)
);
return item.save();
}
update(user, item, data) {
const fields = this._getFiedlNames(user);
const updateData = _.pick(data, fields);
Object.assign(item, updateData);
return item.save();
}
profile.model.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const profileSchema = new Schema({
user: { type: Schema.ObjectId, ref: 'User', required: true },
contactEmail: {
type: String,
required: true,
},
isEnabled: {
type: Boolean,
default: false,
},
about: {
type: String,
default: '',
},
portfolioUrl: {
type: String,
default: '',
},
jobTitle: {
type: String,
default: '',
},
resumeUrl: {
type: String,
default: '',
},
});
module.exports = mongoose.model('Profile', profileSchema);
Then when I try to test this in Postman, I get the following stack "TypeError: Cannot read property '_id' of undefined\n at ProfileService.create (/Users/tj/aydensoft/upwork-ABDS/portfolios/portfolios/services/BaseCrudService.js:46:43)\n at ProfileController.create (/Users/tj/aydensoft/upwork-ABDS/portfolios/portfolios/controllers/BaseCrudContoller.js:20:8)\n
Also the users collection automatically gets the _id:ObjectId("someNumber") when a user is added.
I tried many different ways but it ends up adding a totally different _id:ObjectId("someNumber") instead of the one matching _id:ObjectId("someNumber") in the users collection.
I have a pipeline and its result I want to return it by an express method that is get or not i know if it is more advisable to send it by a socket
this is my file pipeline.js:
function getModel(model) {
model.aggregate([{
$group: {
_id: null,
"price": {
$sum: "$price",
}
}
}]).exec((e, d) => {
return JSON.stringify(d)
})
}
module.exports = getModel;
in the model.js file I'm going to call my pipeline.js file and therefore the function
model.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const getModel = require('./pipeline');
const mySchema = new Schema({
user: {
type: Schema.ObjectId,
ref: 'User'
},
namepet: String,
type_of_service: String,
characteristic_of_pet: String,
price: Number
});
const model = mongoose.model('Cites', mySchema);
here is the function-> getModel(model);
module.exports = model;
and it works for me as I want the problem is that the result I have to send it by a method get and I have no idea how to do it
How can I send the result indicating the red arrow of the image by a get method?
var express = require('express');
var app = express();
function getModel(model) {
model.aggregate([{
$group: {
_id: null,
"price": {
$sum: "$price",
}
}
}]).exec((e, d) => {
return JSON.stringify(d)
})
}
app.get('/', function(req, res) {
console.log('marhaba');
res.send(getModel( ** Model ** ))) //== > here call the getModel function
});
app.listen(3000, function() {
console.log("Working on port 3000");
});
I am trying to create a collection in mongodb where a field named lists will contain an array of link and linkName. I am successfully able to create a two seperate field link and linkName, however not able to store the value inside lists.
Model code for mongodb :-
const socialSchema = new Schema({
lists: [{
link:{ formType: String},
linkName: { formType: String}
}]
})
API code :-(this code is for creating only, will later on try to use findOneAndUpdate to update the existing field
router.route('/', [auth]).post(async (req, res) => {
const {linkName, link } = req.body
try {
console.log(req.body)//Ex. { linkName: 'facebook', link: 'www.facebook.com'}
const social = new Social({
//Stuck here!!!
})
await social.save()
res.json(social)
} catch (err) {
console.error(err.message);
res.status(500).send('Server Errors')
}
}
)
Part of frontend Code(React)
const [formData, setFormData] = useState({
linkName: '',
link: ''
});
const {linkName, link} = formData
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const handleSubmit = async e => {
e.preventDefault()
const socialList = {
linkName,
link
}
try {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify(socialList)
const res = await Axios.post('/api/social', body, config)
console.log(res)
} catch (err) {
console.error(err);
}
}
In your schema change from {formType: String} to {type: String}.
const data = {link: req.body.link, linkName: req.body.linkName};
Social.create({
links: [data]
});
This should work.
MY FULL WORKING CODE THAT I TESTED
const schema = new mongoose.Schema({
links: [
{
link: { type: String },
linkName: { type: String }
}
]
});
const Model = mongoose.model("test", schema);
const doc = { link: "link", linkName: "linkname" };
Model.create({
links: [doc]
});