I'm having difficult coming up with the best possible way of storing todo list items in the backend. I was told that storing array and object in the backend was not a good idea. I'm trying to clone a google keep inspired web app.
Some context: as soon as the user submits their todo list, it will make an axios call to the backend that will iterate through an array of todo list items and save them individually to the backend.
Which inspired me with this current set up.
CREATE TABLE TODO (
ID SERIAL PRIMARY KEY,
title VARCHAR,
user_id INTEGER REFERENCES users(ID));
CREATE TABLE TODO_ITEM (
ID SERIAL PRIMARY KEY,
item VARCHAR,
complete BOOLEAN,
todo_list_id INTEGER REFERENCES TODO(id));
My frontend call to the backend looks like this
toDoArray.map(ele => {
axios.post('users/postToDoListItems', {
item: ele,
complete: false,
todo_list_id: ?
})
})
axios.post('users/postToDoList', {
title: title,
toDoList: toDoList
})
}
The TODO_ITEM table I would like to to reference my TODO table so that when it's called to the frontend and grouped with the correct table.
With my current setup, is it possible to pass the reference (TODO)ID to TODO_ITEM table?
so aaaww i think you made some little mistakes i dont know how you query on your back-end but you must notice that before making your tables you must make a connection to your db soo i think it's not back to check this
or if you did it before plz complete your info about your problem , but the right thing for making queries is this :
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.end();
and for query from front-end you should do this :
<< fron-end >>
axios.post('users/postToDoListItems', {
item: ele,
complete: false,
todo_list_id: 1
})
<< back-end >>
route : postToDoListItems
connection.query(`SET complete = ${req.body.complete} FROM todo WHERE id =${req.body.id}`, function (error, results, fields) {
if (error) throw error;
res.json({results,fields})
});
Related
I've created a private messaging app where users login and can view their private messages. The problem that I am having is that is only shows the message list of one logged in user at a time. So let's say User A is logged in, it will show the chat list of user A. But then User B logs in, then both User A and User B will see the chat list of User B.
This is my server side call to fetch chats by user id:
Im using express for the backend
io.on('connection', socket => {
socket.on('findAllChatsByUserId', (userId) => {
socket.userId = userId
socket.join(socket.userId)
ChatModel.aggregate([{$match: {$or:[{senderId: userId},{receiver: userId}]}}, {$group: {_id: '$chatId', 'data': {$last: '$$ROOT'}}}]).exec(function(error, data) {
if (error) {
return error
} else {
data.sort(function (a, b) {
return b.data.date - a.data.date;
});
io.to(socket.userId).emit('findAllChatsByUserId', data);
}
})
})
});
And on the client side I do:
I am using VueJs on the FE
mounted () {
this.loading = true
this.socket.emit('findAllChatsByUserId', this.getUserId) // this calls the socket to get the chats for the given user Id
this.loading = false
},
I tried creating rooms by userId to make sure that only the data for a given user ID is passed in but it seems like only one user can use the socket at a time. I thought the rooms would solve this issue for me. Do I have to create a separate socket for each user? If so, how do I do that? I've followed the socket.io private messaging tutorial but they use 2 users talking to each other to explain the problem.
So I ended up solving this by doing:
io.to(socket.id).emit('findAllChatsByUserId', data);
instead of:
io.to(socket.userId).emit('findAllChatsByUserId', data);
So you use the "to" attribute to make sure the data you're sending is going to a particular socket, and you can find your specific socket by just calling socket.id (you don't have to set this, it gets set on its own. And the data will get emitted to whomever is on that specific socket.
API runs locally(and in future in a circleCI container) so I don't need to stub responses, only real requests and real responses.
When I send a POST request, it creates an event and returns a big response body containing a unique ID.
I need to store that unique ID somewhere(as env variable, json or worst case scenario a const) so that I can access and use it in UPDATE request later and in the end in DELETE request to delete that Event from the system.
Is there a way to do this?
There is a way to retrieve that ID from the DB, but I really don't want to do it that way
You can save the unique ID in the fixture file and then later update or read from it:
cy.request({
method: 'POST',
url: '/someurl',
}).then((resp) => {
// Expect success response
expect(resp.status).to.eq(200)
//Write Unique ID to a fixture file
cy.writeFile('cypress/fixtures/testdata.json', {
"id": resp.uniqueID
})
})
If you want to update the value of the Unique ID, you can do something like this:
cy.readFile("cypress/fixtures/testdata.json", (err, data) => {
if (err) {
return console.error(err);
};
}).then((data) => {
data.id = newUniqueID //save the New Value of Unique ID
cy.writeFile("cypress/fixtures/testdata.json", JSON.stringify(data)) //Write it to the fixtures file
})
I'm creating a backend using Sequelize. For best practices, I want to return Location header if the user tries to create an duplicated resource. Check my code:
try {
const resource = await Resource.create(data);
return res.status(201).send(resource);
} catch (error) {
// Error handling
switch (error.name) {
case 'SequelizeDatabaseError': return res.status(400).send(error);
case 'SequelizeUniqueConstraintError': {
// Resource location
res.location(`/${_location_}`)
return res.status(409).send(_resource_)
};
}
Obs: I'm not sure if check error.name is the best way to get the error. Please comment others if you know.
Printing the error on the console I found the error details:
{
// ...
ValidationErrorItem {
message: 'name must be unique',
type: 'unique violation',
path: 'name',
value: _value_,
origin: 'DB',
instance: [Resource],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: []
}
],
fields: { name: _value_ },
detail: 'Key (name)=(_value_) already exists.',
// ...
}
Obs: _value_ refers to duplicated value and name to column name.
There is a way to get the id (primary key, uuid, etc.) of the conflicting resource without do another query? If don't, should I really do the query just for return the Location header param?
I also tried it on my local server. I don't think it is possible to get Primary key of the conflicting row.
I would suggest before making .create() call you make .findOne() query so if you found already existing entry then you can return that row so it will also prevent error while creating new entry and it will also save create query on Database.
I'm looking for a way to store the results of this select query like a "rank" chart for a game but I'm not sure if what I'm encountering is an async issue or a data-type issue or something else entirely. Any thoughts?
var ranksVar = [];
db.all("select * from user", function(err, rows){
if(err) {
throw err;
} else {
setValue(rows);
}
});
function setValue(value) {
ranksVar = value;
console.log(ranksVar);
}
I've found out a useful post about using SQLite with NodeJS and it gives you the basic examples needed to understand how to use it. Here it is: SQLite NodeJS
In your case, look under the section data query.
Here the example code:
const sqlite3 = require('sqlite3').verbose();
// open the database
let db = new sqlite3.Database('./db/chinook.db');
let sql = `SELECT DISTINCT Name name FROM playlists
ORDER BY name`;
db.all(sql, [], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.name);
});
});
// close the database connection
db.close();
As you can see, the rows variable is (I guess) a special type created by the module. To get all data from it, you might want to iterate over it and push it into your array variable.
Cheers 😁 !
I figured out the issue. It was a data type/async issue, I was trying to print a string for an undefined array.
Went back a loop and used the JSON.stringify method to display the array objects correctly.
I'm trying to insert data to my Wix collection using the API. I'm using a POST function and am posting a JSON document. It's supposed to simply add a new row to a database containing 1 value.
Here is the http-functions.js which I can trigger without issues (it's more or less a copy of the example from the documentation):
import {created, serverError} from 'wix-http-functions';
import wixData from 'wix-data';
export function post_peopleCount(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
// get the request body
return request.body.text()
.then( (body) => {
// insert the item in a collection
return wixData.insert("NumberOfPeopleDB", JSON.parse(body));
} )
.then( (results) => {
options.body = {
"inserted": results
};
return created(options);
} )
// something went wrong
.catch( (error) => {
options.body = {
"error": error
};
return serverError(options);
} );
}
The database looks like this:
and the JSON I am posting looks like this:
But the Error I am getting is:
But the permissions I have set for the collection is:
Do you know why I might be getting that "WD_PERMISSION_DENIED" and 500 Server Error? (The data does not get entered.)
Thanks!
My friend, its not related to creating a collection from scratch it is because of the permissions set to this collection once created. You fixed that by not noticing :).
Permission need to be given in order to perform such queries.
It turns out, if I create a new collection (= table) from scratch, it works. I also changed the field value in the collection to people, maybe value is a reserved term. Nevertheless, now it seems to work:
So if you run into the same problem: Try recreating the collections from scratch.
The critical thing for me which has not been mentioned yet is that you need to set the collection to have form-like permissions so that anyone has permission to submit data to the collection.