I am trying to filter the data from table in which i want to use multiple condition. when i apply like in query it show application error.
how to do the same?
I am using nodejs framework, express, sequelize and mysql.
router.get('/booking-information', function (req, res) {
// Get orders
Promise.all([Order.findAll({
/*where: {
endDate: null,
},*/
order: [
['id', 'DESC'],
]
}),
Professional.findAll({where: {status : '1'}})
])
.then(([orders, professionals]) => {
orders.map((order) => {
let professionalsInSameArea = professionals.filter((professional) => {
return (professional.service === order.service || professional.secondary_service LIKE '%' + order.service + '%') && (professional.area === order.area || order.area === professional.secondary_area);
});
order.professionals = [...professionalsInSameArea]
return order;
});
res.render('booking-information', {title: 'Technician', orders: orders, user: req.user});
})
.catch((err) => {
console.error(err);
});
});
I want to filter out the professionals in same area and same service for which a order placed.
you can use Op operator in query
like :-
const Op = Sequelize.Op
{
[Op.or]: [
{
fieldName: {
[Op.like]: 'abc%'
}
},
{
fieldName: {
[Op.like]: '%abc%'
}
}
]
}
Believe it or not, You can just use String.indexOf function in your case Because
By definition, String LIKE %word% means if the String contains word:
router.get('/booking-information', function (req, res) {
// Get orders
Promise.all([
Order.findAll({
/*where: {
endDate: null,
},*/
order: [
['id', 'DESC'],
]
}),
Professional.findAll({
where: {
status: '1'
}
})
])
.then(([orders, professionals]) => {
orders.map((order) => {
let professionalsInSameArea = professionals.filter((professional) => {
return (professional.service === order.service
|| (professional.secondary_service || '').toLowerCase().indexOf((order.service || '').toLowerCase()) > -1)
&& (professional.area === order.area
|| order.area === professional.secondary_area);
});
order.professionals = professionalsInSameArea; //you don't need to spread, then make an array
return order;
});
res.render('booking-information', { title: 'Technician', orders: orders, user: req.user });
})
.catch((err) => {
console.error(err);
});
});
Related
I have a problem on my application, it is a social network. The user can create a post with a message and an image, stored in a backend images folder thanks to Multer. I use sequelize and MySql. When I delete a post, the image is indeed deleted in the images folder since I use multer in my post deletion function so everything goes well but when I delete the author, since I go through a relationship between tables so that when I delete a user, their posts are deleted. This works but in this case the images are not deleted from the folder they are stored in, since Multer is not in the loop. How do I get the images to be deleted from the images folder too in this specific case? Thank you for your help !
`
// Template for the Post table
const User = require("../models/User");
const Sequelize = require("sequelize");
const database = require("../config/database");
const Post = database.define("post", {
content: { type: Sequelize.STRING, allowNull: false },
image: { type: Sequelize.STRING, allowNull: true },
likes: { type: Sequelize.INTEGER, allowNull: false, default: 0 },
});
module.exports = Post;
// Relationship with the User table
User.hasMany(Post, { onDelete: "CASCADE", foreignKey: "userId" });
Post.belongsTo(User, { onDelete: "CASCADE" });
`
`
// deletePost function
exports.deleteOnePost = (req, res, next) => {
Post.findOne({ where: { id: req.params.id } })
.then((post) => {
if (!post) {
return res.status(404).json({
error: new Error("Post non trouvé !"),
});
}
if (post.userId === req.auth.userId || req.auth.userAdmin) {
if (post.image) {
const filename = post.image.split("/images/")[1];
fs.unlink(`images/${filename}`, () => {});
}
Post.destroy({ where: { id: req.params.id } })
.then(() => res.status(200).json({ message: "Post sans supprimé" }))
.catch((error) => res.status(400).json({ error }));
} else {
return res.status(403).json({
error: new Error("Requête non autorisée !"),
});
}
})
.catch((error) => res.status(500).json({ error }));
};
`
#Anatoly Thank you very much for your help, I'm sorry, I'm a beginner, I tried to adapt what you sent me to the method I use. I don't use the async/await method much and don't know much about it. Do you think I'm getting closer to the solution with what i made ? thanks again !
`
exports.deleteUser = (req, res, next) => {
const userId = req.params.id;
User.findOne({ where: { id: userId } }).then((user) => {
if (!user) {
return res.status(404).json({
error: new Error("User not found!"),
});
}
});
const userPosts = User.getAllPosts();
const postImages = posts.map((x) => x.image).filter((x) => x);
User.destroy({ where: { id: userId } })
.then((post) => {
Post.findOne({ where: { userId } })
.then((post) => {
Post.destroy({ where: { userId } }).then((res) =>
res.status(200).json({
message: "User is deleted",
})
);
for (const image of postImages) {
const filename = image.split("/images/")[1];
fs.unlink(`images/${filename}`, () => {});
}
})
.catch((error) =>
res.status(400).json({
error,
})
);
})
.catch((error) => res.status(500).json({ error }));
};
`
I don't see how Multer is related to a file deletion. It only helps you to store them. Any way you just need to get all posts of a certain user and delete them and a user in a transaction and then delete their images in a cycle:
// I did not use try/catch for simplicity
exports.deleteUser = async (req, res, next) => {
// get the user id somehow (req.params or the request context, for instance)
const userId = ...
const user = await User.findById(userId);
if (!user) {
return res.status(404).json({
error: new Error("User not found!"),
});
}
const userPosts = await user.getPosts();
const postImages = poists.map(x => x.image).filter(x => x);
// here 'sequelize' is the Sequelize instance, you used to register models
await sequelize,transaction(async transaction => {
await Post.destroy({ where: { userId } })
await User.destroy({ where: { id: userId } })
});
for (const image of postImages) {
const filename = image.split("/images/")[1];
fs.unlink(`images/${filename}`, () => {});
}
res.status(200).json({ message: "User is deleted" }))
}
I come back to put the fonction that works with my method, i often use ".then()" ".catch()", many thanks to Anatoly for helping me to find the solution, here is the result of my work :
exports.deleteUser = (req, res, next) => {
User.findOne({ where: { id: req.params.id } })
.then((user) => {
if (!user) {
return res.status(404).json({
error: new Error("user not found !"),
});
}
// I get all the posts of the author
Post.findAll({ where: { userId: req.params.id } })
.then((posts) => {
// I start a loop in the posts of the author to find the posts with an image
posts.forEach((post) => {
if (post.image) {
// I erase the files in the images backend directory
const filename = post.image.split("/images/")[1];
fs.unlink(`images/${filename}`, () => {});
}
// Now i can erase the author
User.destroy({ where: { id: req.params.id } })
.then(() =>
res.status(200).json({
message: "User erased !",
})
)
.catch((error) =>
res.status(400).json({
error,
})
);
});
})
.catch((error) =>
res.status(400).json({
error,
})
);
})
.catch((error) => res.status(500).json({ error }));
};
I have this function where i have to return/display the value of results, I'am using react native and couchDB as my database this code is inside of a flatlist. I have tried this one but it is not working. please help me with this one.
vacant (room) {
localNoteDb
.find({
selector: {
status: "vacant",
room_type: room
},
fields: ['_id', 'room_type', 'room_no' ,'price','status','user', 'updated_at', 'hour_status', 'price_per'],
use_index: nameIndex_status.status,
sort: [{status: 'asc'}]
})
.then(result => {
console.log('getListNoteFromDb', result)
let getLenght = result.doc
const results= Object.keys(result).length
console.log('value of results: ', results)
return(
<Text> {Object.keys(result).length}</Text>
);
})
}
Try this way
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount
useEffect(() => {
vacant(...);
});
const vacant (room) {
localNoteDb
.....
.....
.then(result => {
console.log('getListNoteFromDb', result)
let getLenght = result.doc
const results= Object.keys(result).length
setCount(results); <-- This way -->
});
}
return (
<Text> {count}</Text>
);
}
so I follow up this documentation for creating a editable row; It's a CSS library for React from Ant Design, I am stuck at the following:
How do I pass the changed row, the newData[index] to an onChange event?
How do I update a set of row of data to a back-end rest api? I managed to create data using form from Ant Design, but I don't know how to update it using editable row
Fyi, the back end works perfectly with postman: create, update, delete
How do I get the id of this code?
axios.put("/api/product/update/:id"
I tried to replace the id with ${id}, ${index}, ${products[index]} (with template literal) but it doesn't work.
Here are the full code:
import React from 'react';
import axios from 'axios';
import { Table, Input, InputNumber, Popconfirm, Form } from 'antd';
const FormItem = Form.Item;
const EditableContext = React.createContext();
const EditableRow = ({ form, index, ...props }) => (
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
);
const EditableFormRow = Form.create()(EditableRow);
class EditableCell extends React.Component {
getInput = () => {
if (this.props.inputType === 'number') {
return <InputNumber />;
}
return <Input />;
};
render() {
const {
editing,
dataIndex,
title,
inputType,
record,
index,
...restProps
} = this.props;
return (
<EditableContext.Consumer>
{(form) => {
const { getFieldDecorator } = form;
return (
<td {...restProps}>
{editing ? (
<FormItem style={{ margin: 0 }}>
{getFieldDecorator(dataIndex, {
rules: [{
required: true,
message: `Please Input ${title}!`,
}],
initialValue: record[dataIndex],
})(this.getInput())}
</FormItem>
) : restProps.children}
</td>
);
}}
</EditableContext.Consumer>
);
}
}
class EditableTable extends React.Component {
constructor(props) {
super(props);
this.state = { products: [], editingKey: '' };
this.columns = [
{
title: 'Product Name',
dataIndex: 'productname',
width: '25%',
editable: true,
},
{
title: 'OS',
dataIndex: 'os',
width: '10%',
editable: true,
},
{
title: 'Category',
dataIndex: 'category',
width: '15%',
editable: true,
},
{
title: 'Model',
dataIndex: 'model',
width: '20%',
editable: true,
},
{
title: 'Serial Number',
dataIndex: 'serialnumber',
width: '20%',
editable: true,
},
{
title: 'Operation',
dataIndex: 'operation',
width: '10%',
render: (text, record) => {
const editable = this.isEditing(record);
return (
<div>
{editable ? (
<span>
<EditableContext.Consumer>
{form => (
<a
href="javascript:;"
onClick={() => this.save(form, record.id)}
style={{ marginRight: 8 }}
>
Save
</a>
)}
</EditableContext.Consumer>
<Popconfirm
title="Sure to cancel?"
onConfirm={() => this.cancel(record.id)}
>
<a>Cancel</a>
</Popconfirm>
</span>
) : (
<a onClick={() => this.edit(record.id)}>Edit</a>
)}
</div>
);
},
},
];
}
handleCategoryChange = event => { this.setState({ category: event.target.value }) }
handleProductNameChange = event => { this.setState({ productname: event.target.value }) }
handleOsNameChange = event => { this.setState({ os: event.target.value }) }
handleModelchange = event => { this.setState({ model: event.target.value }) }
handleSerialnumberChange = event => { this.setState({ serialnumber: event.target.value }) }
handlePriceChange = event => { this.setState({ price: event.target.value }) }
handleEquipmentChange = event => { this.setState({ equipment_condition: event.target.value }) }
handleDetailChange = event => { this.setState({ detail: event.target.value }) }
handleImageChange = event => { this.setState({ image: event.target.value }) }
handleSubmit = event => {
event.preventDefault();
axios.put(`/api/product/update/:id`,
{
category: this.state.category,
productname: this.state.productname,
os: this.state.os,
serialnumber: this.state.serialnumber,
model: this.state.model,
price: this.state.price,
equipment_condition: this.state.equipment_condition,
detail: this.state.detail,
image: this.state.image
})
}
componentDidMount() {
axios.get('/api/product').then(res => {
this.setState({ products: res.data });
});
}
isEditing = (record) => {
return record.id === this.state.editingKey;
};
edit(id) {
console.log('products', this.state.products.id);
// console.log('recordid', record.id);
this.setState({ editingKey: id });
}
save(form, id) {
console.log('key', id)
form.validateFields((error, row) => {
if (error) {
return;
}
const newData = [...this.state.products];
const index = newData.findIndex(item => id === item.id);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...row, });
this.setState({ products: newData, editingKey: '' });
console.log('newData', newData[index]) // data I want to update to API
console.log('category', newData[index].category) // category
} else {
newData.push(this.state.products);
this.setState({ products: newData, editingKey: '' });
}
});
}
cancel = () => {
this.setState({ editingKey: '' });
};
render() {
const components = {
body: {
row: EditableFormRow,
cell: EditableCell,
},
};
const columns = this.columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
inputType: col.dataIndex === 'serialnumber' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: this.isEditing(record),
}),
};
});
return (
<Table
rowKey={this.state.id}
components={components}
bordered
dataSource={this.state.products}
columns={columns}
rowClassName="editable-row"
/>
);
}
}
export default EditableTable;
Update:
So I try put axios inside the save method, like so:
save(form, id) {
form.validateFields((error, row) => {
if (error) {
return;
}
const newData = [...this.state.products];
const index = newData.findIndex(item => id === item.id);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...row, });
this.setState({ products: newData, editingKey: '' });
console.log('newData', newData[index]) // data I want to update to API
console.log('index', index) // index adalah index array
console.log('id', id) // id adalah nomor index dalam tabel database, jangan sampai tertukar
console.log('category', newData[index].category)
console.log('productname', newData[index].productname)
console.log('os', newData[index].os)
console.log('serialnumber', newData[index].serialnumber)
console.log('model', newData[index].model)
console.log('detail', newData[index].detail)
axios.put(`/api/product/update/:${id}`,
{
category: newData[index].category,
productname: newData[index].productname,
os: newData[index].os,
serialnumber: newData[index].serialnumber,
model: newData[index].model,
price: newData[index].price,
equipment_condition: newData[index].equipment_condition,
detail: newData[index].detail,
image: newData[index].image
})
} else {
newData.push(this.state.products);
this.setState({ products: newData, editingKey: '' });
}
});
It doesn't update the data on the database.
Someone might still need this, The antd table api.
You can pass the render key in your column with one to three parameters depending on what you need
function(text, record, index) {}
The column will look like this:
const column = [{
dataIndex: "firstName",
render: (text, record, index) => console.log(text, record, index)
}]
So there's this weird syntax that I have to remove from the url api.
Pay attention to the very minor details of the url; I noticed it from the console log from the back end / node:
axios.put(`/api/product/update/${id}`,
{
category: newData[index].category,
productname: newData[index].productname,
os: newData[index].os,
serialnumber: newData[index].serialnumber,
model: newData[index].model,
price: newData[index].price,
equipment_condition: newData[index].equipment_condition,
detail: newData[index].detail,
image: newData[index].image
})
I had created 2 tables named: groupusermaps and groups. From groupusermaps i am fetching all the groupId and these groupId I am passing in findById() method to fetch all the details related to that groupId inside the for loop.
here is my method in service:
getAllGroupsByUserId(userId, callback) {
var arr = [];
return sequelize.transaction().then(function(t) {
return groupUserMapModel.GroupUserMap.findAll({
where: {
userId: userId
},
transaction: t
}).then((allGroupsByUserId) => {//from findAll i am getting 2, 1, 4
groupId
for (var p in allGroupsByUserId) {
return
groupModel.Group.findById(allGroupsByUserId[p].groupId, { transaction: t
}).then((group) => {
arr.push(
JSON.stringify(group)
);
});
}
}).then(() => {
callback(arr);
});
});
}
my controller code:
router.get('/controllers/getGroups/user/:userId/groups', (req, res) => {
groupService.getAllGroupsByUserId((req.params.userId), (result) => {
log.info('Group list: ' + JSON.stringify(result));
});
res.send('Fetched all group list');
});
But I am getting an empty array as response from the controller on the console. Is there any way to fix this issue?
groupUserMapModel.GroupUserMap.findAll({
where: {
userId: userId
},
include:[{
model:groupModel
}]
})
.then((results) => {
console.log(results);
})
.catch(err=>{
console.log(err);
})
// provided that groupUserMapModel associated to groupModel
groupUserMapModel.associate = models => {
groupUserMapModel.belongsTo(models.groupModel, {foreignKey: groupId})
}
for more info read about sequelize association
I am working on a calculator using MERN stack but my client and server are different projects. React App is running on 3030 and Node Backend on 3000. I am able to retrieve the correct response from Node Backend, but not able to update it to the store, mostly due to the issue with the scope of 'state' or returned data. Below is my code snippet :
const calcReducer = (state = calcState, action) => {
switch(action.type){
case 'ADD_ELEM':
return {
...state,
value: state.value == 0 ? action.text : state.value + action.text
}
case 'CLEAR':
return{
...state,
value: 0
}
case 'EQUAL':
const url = 'http://localhost:3000/calculate';
superagent
.post(url)
.send({ exp : state.value })
.set('Accept', 'application/json')
.end((err,data) => {
if (err)
return state;
else {
console.log(state); //prints the old value of the state
//below prints the correct state value but returning the state from here doesn't work
console.log({
...state,
value : Number(JSON.parse(data.text).result)
})
}
})
return {
...state,
value : VALUE // how can the value be brought here from inside of else loop
}
default:
return state;
}
}
console.log statement inside 'else' prints correctly but no effect if I return state value from there. The place from where I am currently returning 'state' is not working out for me, and the returned state is exactly same as the state before the control came inside the case. Can someone please explain me how to work with the scope as I am new to ES6?
Edit1:
When I try to take the 'async-ness' out of the reducer, and make change as given below:
const mapStateToProps = (state) => {
return{
value: state.value,
btns: state.btns
}
}
const mapDispatchToProps = (dispatch) => {
return{
addElem: (text) => {
dispatch({
type: 'ADD_ELEM',
text
})
},
clear: () => {
dispatch({
type: 'CLEAR'
})
},
equal: (value) => {
console.log(value)
superagent
.post('http://localhost:3000/calculate')
.send({ exp : value })
.set('Accept', 'application/json'))
.end((err,data) => {
dispatch({ type: 'EQUAL', JSON.parse(data.text).result })
})
}
}
}
In this case, code build fails saying:
Module build failed: SyntaxError: Unexpected token (74:2)
72 |
73 | const mapStateToProps = (state) => {
> 74 | return{
| ^
75 | value: state.value,
76 | btns: state.btns
77 | }
There are syntax errors in your mapDispatchToProps, try to well indent your code so it will be more easy to identify them.
const mapDispatchToProps = (dispatch) => {
return {
addElem: (text) => {
dispatch({
type: 'ADD_ELEM',
text
})
},
clear: () => {
dispatch({
type: 'CLEAR'
})
},
equal: (value) => {
console.log(value)
superagent
.post('http://localhost:3000/calculate')
.send({ exp : value })
.set('Accept', 'application/json')
.end((err,data) => {
dispatch({ type: EQUAL, result: JSON.parse(data.text).result })
})
}
};
};
The return statement is within a callback function. So, you are returning only from the callback function. You probably should wrap it in a Promise as follows.
return new Promise((resolve, reject) => {
superagent(...)
...
.end((err, data) => {
if (err)
reject(state);
else {
resolve({
...state,
value : Number(JSON.parse(data.text).result)
});
}
});
});