How to cast string boolean from MySQL to real boolean in Javascript? - javascript

I built a php backend for my ReactJS frontend.
My mysql users table has a checkedIn column that is stored as tinyint. I am fetching it like:
<?php
// ...
$getUser = "SELECT * FROM `users` WHERE `uid`=:uid AND `unique_id`=:unique_id";
$getUser_stmt = $conn->prepare($getUser);
$getUser_stmt->bindValue(':uid', $uid,PDO::PARAM_STR);
$getUser_stmt->bindValue(':unique_id', $unique_id,PDO::PARAM_STR);
$getUser_stmt->execute();
//...
And in my frontend:
useEffect(() => {
axios
.get(`${config.server}/api/user.php?uid=${match.params.uid}`)
.then((result) => {
console.log(result.data.message);
setUser(result.data.message);
})
.catch((error) => console.error(error));
}, [match.params.uid]);
My log gives me:
{
"id": "5",
"uid": "A0005",
"unique_id": "1384773b4df62",
"mail": "mail#test.com",
"date_checkin": "2021-05-03 11:00:35",
"checkedIn": "1"
}
How can I modify my backend or my frontend, to have a real boolean value for checkedIn in the frontend?
I expect:
{
"id": 5,
"uid": "A0005",
"unique_id": "1384773b4df62",
"mail": "mail#test.com",
"date_checkin": Date Mon May 03 2021 17:15:27 GMT+0200,
"checkedIn": true
}
As a side effect: How can I cast the id to Number and the timestamp to Date?

Create a function convert do these conversion:
let user = `{
"id": "5",
"uid": "A0005",
"unique_id": "1384773b4df62",
"mail": "mail#test.com",
"date_checkin": "2021-05-03 11:00:35",
"checkedIn": "1"}`;
function convert(data){
data["id"] = data["id"]*1;//Int
data["checkedIn"] = !(data["checkedIn"]==='0');//Bool
data["date_checkin"] = Date(data["date_checkin"]);//Date
return data;
}
convert(JSON.parse(user));
Note: user has JSON format. So convert it to real object using function JSON.parse()

Related

Wrong results in group_by by month with javascript date objects in node app

I have a problem using javascript date objects in a node app and running queries through postgresql.
I have following data in a csv file (first column: date, second column: amount)
08/08/2022;620,00
01/08/2022;-73,41
01/08/2022;600,00
01/08/2022;-341,36
Since date format is not standard, I convert it manually to a date object:
new Date(year, month, day);
I store it to a postgresql database through the prisma client.
The date field is following type in schema.prisma
model Transaction {
id Int #id #default(autoincrement())
amount Float
date DateTime #db.Date
which corresponds to this migration:
ALTER TABLE "Transaction" ALTER COLUMN "date" SET DATA TYPE DATE;
Once data is stored, it looks like this:
[
{
"id": 9205,
"date": "2022-08-07T22:00:00.000Z",
},
{
"id": 9206,
"amount": -73.41,
"date": "2022-07-31T22:00:00.000Z",
},
{
"id": 9207,
"amount": 600,
"date": "2022-07-31T22:00:00.000Z",
},
{
"id": 9208,
"amount": -341.36,
"date": "2022-07-31T22:00:00.000Z",
}
]
Dates look good, I double-checked running .getMonth, creating the date again in the browser etc.
I try to run a raw query with prisma:
const expensesByMonths: any[] = await this.prisma.$queryRaw`
SELECT
date_trunc('month', date) as date_month,
sum(amount)
FROM "public"."Transaction"
GROUP BY
date_month
`;
Unfortunately, the results are wrong:
{
"expensesByMonths": [
{
"date_month": "2022-07-01T00:00:00.000Z",
"sum": -414.77
}
],
"incomesByMonths": [
{
"date_month": "2022-07-01T00:00:00.000Z",
"sum": 600
},
{
"date_month": "2022-08-01T00:00:00.000Z",
"sum": 620
}
]
}
I don't understand why group_by from postgresql is not understanding the javascript date objects, since they are strings at the end.
I guess I can't store in postgresql things like 2022-07-31T22:00:00.000Z, I see everywhere dates like '2022-11-23', not sure if it's stored as strings or dates

flattening nested objects typescript

I am looking to flatten a nested object in my controller (new to Loopback and Typescript)
Here is my model :
export class SampleModel {
id: number;
code: number;
guide?: string;
gradeData?: string;
}
Here is an example object :
{
"id": 1,
"code": 12345,
"guide": "Guide for 2021",
"gradeData": {
"en": "Eng grade",
"de": "Ger grade"
}
}
Here is my controller:
// returns an array of SampleModel objects
#get('/guides')
async find(
#param.query.string('lang') lang: string,
#param.filter(SampleModel) filter?: Filter<SampleModel>
): Promise<SampleModel[]> {
return this.sampleModelRepository.find(filter); //this returns Promise<SampleModel[]>
}
I want to tweak this response a little based on lang. For ex: if lang = en I want the response to look like
[
{
"id": 1,
"code": 12345,
"guide": "Guide for 2021",
"gradeData": "Eng grade"
}
]
Something like this?
Ofcource you need to make the langcode dynamic
[{
"id": 1,
"code": 12345,
"guide": "Guide for 2021",
"gradeData": {
"en": "Eng grade",
"de": "Ger grade"
}
}].map(e=>{
e.gradeData = e.gradeData["en"];
return e;
})
Returned object:
[
{
"id": 1,
"code": 12345,
"guide": "Guide for 2021",
"gradeData": "Eng grade"
}
]
Thanks to #Firewizz I was able to do this. Here is my updated controller :
// returns an array of SampleModel objects
#get("/guides")
async find(
#param.query.string("lang") lang: string,
#param.filter(SampleModel) filter?: Filter<SampleModel>
): Promise<SampleModel[]> {
const res = this.sampleModelRepository.find(filter); //this returns Promise<SampleModel[]>
if (lang != null) {
(await res).map((e) => {
if (e.gradeData != null && e.gradeData.hasOwnProperty(lang)) {
e.gradeData = new Map(Object.entries(e.gradeData)).get(locale);
// not sure why this is required but when I tried
// `e.gradeData = e.gradeData[locale];`
// I get compilation error " Element implicity has an 'any' type because index expression is not of type 'number' " maybe because gradeData is defined as a String but when I do
// console.log(typeof e.gradeData)
// I get object
// I also tried
// `e.gradeData = JSON.parse(e.gradeData)[locale];`
// I get " SyntaxError: Unexpected token o in JSON at position 1 " and that could be because it's already an object
// I then tried
// `e.gradeData = JSON.parse(JSON.stringify(e.gradeData))[locale];`
// this also works but I think converting this to a map as a workaround is better
}
return e;
});
}
return res;
}

convert all array object(firestore timestamp) to date

I am using firestore and react-native-gifted-chat, I am trying to get all the chat messages from firestore to the chat. However, gifted chat does not support displaying firebase timestamp. It will show invalid Date. Therefore, I m trying to convert all the date object.
async _getMessage() {
const messColRef = db.collection('Message').doc(this.state.roomName).collection('message').orderBy('createdAt', 'desc').limit(9)
const initialQuery = messColRef
const documentSnapshots = await initialQuery.get()
const documentData = documentSnapshots.docs.map(document => ({
id: document.id, ...document.data()
}));
const lastVisible = documentData[documentData.length - 1]
const finalData = _.forEach(documentData['createdAt'], (item) => {
return item.toDate()
});
console.log(documentData)
}
and it is how my data look like:
{
"_id": "f0feb0b6-c0f9-4735-a93d-4297872a4840",
"createdAt": Timestamp {
"nanoseconds": 382000000,
"seconds": 1568995812,
},
"id": "Uw6PNNsf7aqWrxcgSDSi",
"text": "Hi",
"user": {
"_id": "V8h2iSllhPXSr8sTGP0yHiaYZwx1",
"avatar": "https://firebasestorage.googleapis.com/v0/b/exit-3684f.appspot.com/o/add-
user.png ? alt = media & token=395c8beb - 47a3 - 4ae6 - a0a1 - fe901e7ad42f",
"name": "This is the username",
},
},
{
"_id": "cc298d96-f19a-4ec7-bdf7-3767d900a364",
"createdAt": Timestamp {
"nanoseconds": 373000000,
"seconds": 1568995733,
},
"id": "WzbOA52Y3qukvPUIXRLB",
"text": "hello",
"user": {
"_id": "V8h2iSllhPXSr8sTGP0yHiaYZwx1",
"avatar": "https://firebasestorage.googleapis.com/v0/b/exit-3684f.appspot.com/o/add-
user.png ? alt = media & token=395c8beb - 47a3 - 4ae6 - a0a1 - fe901e7ad42f",
"name": "This is the username",
},
},
so my goal is to convert all the createdAt to js time date
Sorry for not explore deeply, after checking #Spatz comments I figure out how to do it
documentData.forEach(a => {
var date = a.createdAt.toDate()
data.push({
_id: a._id,
createdAt: date,
id: a.id,
text: a.text,
user: a.user
})
})
Use renderTime prop of gifted chat and pass a function which converts the time and return that time in a string.

Update one item inside JSON object instead of writing whole file

I'm currently learning Node.js, at the moment I have a JSON file (called cars.json) which is as follows:
[
{
"id": 1,
"brand": "BMW",
"bookedUntil": null
},
{
"id": 2,
"brand": "Mercedes",
"bookedUntil": null
},
{
"id": 3,
"brand": "Golf",
"bookedUntil": null
},
{
"id": 4,
"brand": "Holden",
"bookedUntil": null
},
{
"id": 5,
"brand": "Subaru",
"bookedUntil": null
}
]
I have a PUT method which gets passed an ID value, this ID value is associated with an item inside the JSON object.
The method is as follows:
const data = require('./public/cars.json'); // JSON FILE
app.put('/booking/:id', (req, res) => {
data.forEach((car) => {
if (car.id == req.params.id) {
var date = new Date();
date.setDate(date.getDate() + 1);
car.bookedUntil = date;
}
})
fs.writeFile('./public/cars.json', JSON.stringify(data, null, 2), (error) => {
if (error) {
} else {
res.send('Booking has been made');
}
});
});
All I am doing is finding the record that matches the ID, updating the bookedUntil field with a date in the future i.e one day then re-writing the file back to disk.
Now this is working as expected, however I'm curious to find out if I can just update one item without having to loop and re-write the whole file again?

How to compare a string to a date in postman test?

Suppose a API request fetches a users id, email address and birthday. Sample API Request below:
GET: /v1/users HTTP/1.1
Content-Type: application/json
Authorization: bearer {access_token}
For the above request, the following is the response:
{
"content": [
{
"id": 1,
"email": "random#random.com",
"birthday": "1990-01-01"
},
{
"id": 40,
"email": "random1#random1.com",
"birthday": "1990-18-10"
}
],
"last": false,
"total_elements": 2,
"total_pages": 1,
"sort": null,
"first": true,
"number_of_elements": 2,
"size": 20,
"number": 0
}
Now, what will be the test in postman to make sure that all the returned values under birthday node is greater than 1988-18-01?
I have tried the following:
pm.test("Check birthday greater than 1988-18-01", () => {
for (i = 0; i < jsonData.content.length; i++) {
var a = '1988-18-01';
pm.expect(jsonData.content[i].birthday).to.be.above(a);
}
});
But postman says: "Check birthday greater than 1988-18-01 | AssertionError: expected '1990-01-01' to be a number or a date".
So firstly, the dates need to be converted to a format that JS accepts and use the Date constructor to generate the complete date.
Next, the 'above' function in pm accepts an integer, so the date format will not be compared.
To fix this, we can convert the date to integer format by using the .getTime() function.
Lastly, it's not a good practice to declare variables inside a for loop.
Here's what you can replace your test with:
pm.test("Check birthday greater than 1988-18-01", () => {
let date,
isoFormatDate,
a = new Date('1988-01-18').getTime();
for (i = 0; i < jsonData.content.length; i++) {
date = jsonData.content[i].birthday;
isoFormatDate = new Date(date).getTime(); // Converting to integer from date format
pm.expect(isoFormatDate).to.be.above(a);
}
});

Categories