How to display image from MySQL in ReactJS using Express - mysql

I have uploaded an image in the images folder of my Node server and the path is stored in the MYSQL database. I want to display the image in my ReactJS application. I am getting the error:
http://127.0.0.1:8080/images/abc.jpg 404 (Not Found)
const baseURL = "http://localhost:8080/data";
export default function Displaydata() {
const [userdata, setuserdata] = React.useState([]);
React.useEffect(() => {
axios.get(baseURL)
.then((response) => {
setuserdata(response.data);
console.log(response.data);
});
}, []);
if (!userdata) return null;
return (
<>
<h2>Data</h2>
<table border="1">
<thead>
<tr>
<th>S.No</th>
<th>userid</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{userdata.map(({ userid, name,image },index) => {
let sno=0;
return (
<tr key={userid}>
<td>{index + 1}</td>
<td>{userid}</td>
<td>{name}</td>
<td><img src={image} alt={image}/></td>
</tr>
);
})}
</tbody>
</table>
</>
);
}
What can I try to fix this?

Related

React.js datatable data filter by datepicker and get sum value of column

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Form } from "react-bootstrap";
function SalesReport() {
const [Data, setData] = useState([]);
useEffect(() => {
fetchData();
}, []);
const fetchData = () => {
axios.get("http://localhost:4000/api/cash/showInvoices").then((res) => {
const getData = res.data.data;
setData(getData);
});
};
return (
<div className="row">
<div className="card">
<div className="card-body">
<div className="d-inline-flex col-2 m-2">
<Form.Group controlId="dob">
<Form.Label>Start Date</Form.Label>
<Form.Control
type="date"
name="startDate"
placeholder="Date of Birth"
/>
</Form.Group>
<div className="ms-3">
<Form.Group controlId="dob">
<Form.Label>End Date</Form.Label>
<Form.Control
type="date"
name="enddate"
value={}
placeholder="Date of Birth"
/>
</Form.Group>
</div>
<div className="ms-2 mt-4">
<button className="btn btn-secondary btn-lg" type="button">
Print
</button>
</div>
</div>
<table
id="datatable-buttons"
className="table table dt-responsive nowrap w-100"
>
<thead>
<tr>
<th width="100px">Date</th>
<th>Invoice Id</th>
<th>Pay Method</th>
<th>Total</th>
<th>Customer Id</th>
<th>Cart Id</th>
</tr>
</thead>
<tbody>
{Data &&
Data.map((items) => {
return (
<tr>
<td> {new Date(items.date).toLocaleDateString()}</td>
<td>{items.invoice_id}</td>
<td>{items.pay_method}</td>
<td>{items.total}</td>
<td>{items.customer_id}</td>
<td>{items.inovice_cart_id}</td>
</tr>
);
})}
</tbody>
<tfoot>
<tr className="text-black font-weight-bol">
<td>
<h5 className="total-label">Grand Total</h5>
</td>
<td className="total-col">
<label></label>
</td>
<td className="total-col">
<label></label>
</td>
<td className="total-col">
<label>2234</label>
</td>
<td className="total-col">
<label></label>
</td>
<td className="total-col">
<label></label>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
);
}
export default SalesReport;
**backend**
*router.js*
const {
getInvoice,
viewInvoiceByDate,
} = require("./cashManagement.controller");
const router = require("express").Router();
const cors = require("cors");
router.get("/showInvoices", getInvoice);
module.exports = router;
*controller.js*
const { getInvoice, viewInvoiceByDate } = require("./cashManagement.service");
module.exports = {
getInvoice: (req, res) => {
getInvoice((err, results) => {
if (err) {
console.log(err);
return;
}
return res.json({
success: 1,
data: results,
});
});
},
}
*service.js*
const pool = require("../../config/database");
module.exports = {
getInvoice: (callBack) => {
var todayDate = new Date().toISOString().slice(0, 10);
pool.query(
`SELECT * FROM cash_management WHERE date='${todayDate}'`,
(errors, results, fields) => {
if (errors) {
return callBack(errors);
}
return callBack(null, results);
}
);
},
}
That picture shows what I'm trying to do. by default today's relevant data show. it took from using "new Date()" method using with mysql select query . So , if I want to get particular days period data , I should select it from data picker. There is two datapickers . one for starting date, second one for end data selecting. if I select just start date , I need data from that day to today . otherwise if I select just endDate , I need to get data from today to end date . so I tried to that someways. It doesn't work properly. My backend code here ,it contains how I got data from database . I just got data from using "newDate()" method to took today data. how it should be changed when entering start date and end date . otherwise here table you can see the total column . and table footer has "GrandTotal " 4th column should get the total values of "total columns" previously I took it direct from database. but now cant , because it is changed by quickly. I think you have clear idea about issue. I tried many ways , but it didn't work. if there any expert help me to solve the issue.

MySQL procedure returns two unnamed arrays

Im building an app with ReactJS and MySQL database and I have a problem - the API/MySQL returns two arrays with no names.
Calling it from my API which uses MySQL (db) and Express (app)
app.get("/api/getInventory", (req, res) => {
const PlayerID = 1
const sqlSelect =
"call pInventory_select(?)"
db.query(sqlSelect, PlayerID, (err, result)=> {
//console.log(err)
res.send(result)
});
})
returns two arrays with no names:
And returning the JSON data here:
import Axios from 'axios'
import { useState, useEffect } from "react";
export default function Inventory() {
const [Inventory, setInventory] = useState([])
useEffect(() => {
Axios.get('http://localhost:3030/api/getInventory').then((response)=> {
setInventory(response.data);
})
}, [])
console.log(Inventory)
return (
<main className="text-xl font-bold text-slate-200">
<h2 className="text-3xl font-bold text-slate-200">Inventory 🎒</h2>
<table className=''>
<tr>
<th>Skin name</th>
<th>Grade</th>
<th>Wear</th>
<th>Collection</th>
<th>Price</th>
<th>Amount</th>
</tr>
{Inventory.map(item => (
<tr>
<td className='px-2'>{item.SkinName}</td>
<td className='px-2'>{item.RarityName}</td>
<td className='px-2'>{item.QualityName}</td>
<td className='px-2'>{item.CaseName}</td>
<td className='px-2'>{item.ItemPrice}</td>
<td className='px-2'>{item.Amount}</td>
</tr>
))}
</table>
</main>
);
}

How to create table handlebars with nodejs

Guys I have the following json server.js:
const express = require("express")
const app = express()
const http = require('http').Server(app);
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('./conta.sql')
const handlebars = require("express-handlebars");
const bodyParser = require("body-parser")
app.use(express.static(__dirname + "/css/"));
app.use(bodyParser.urlencoded({extended:true}));
app.engine('handlebars', handlebars({defaultLayout:false}));
app.set('view engine', 'handlebars');
function getallusers(req,res) {
try{
data = [
{
id: 1,
nome: 'Ronnica Hardison',
data: '2021-09-31 04-54-00',
email: 'test#gmail.com',
nome_bonus: 'John Watson',
cod_bonus: 'piwi20k9'
},
{
id: 2,
nome: 'Kellie Jean Abernethy',
data: '2021-09-31 23-50-00',
email: 'gobirob190#mnqlm.com',
nome_bonus: 'Ámelia Barton',
cod_bonus: 'piwiki20k9'
}
]
res.render(__dirname + "/index.handlebars")
}
catch(err){
console.log("\x1b[31m Problema ao carregar as informações do banco de dados!",err);
}
}
app.get('/', function(req,res){
getallusers(req,res)
});
http.listen(8083,() => {
console.log("Servidor escutando na porta 8083");
});
index.handlebars:
<center>
<div class="table">
<table cellspacing="0">
<thead>
<tr class="indices">
<th>Nome</th>
<th>Email</th>
<th>Data de Criação</th>
<th>Convidada de</th>
<th>Codico usado</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
{{data here}}
</tr>
</tbody>
</table>
</div>
</center>
So guys... what I needed to do was render the json data in the table, how can I do this? What I need is to create <th> tags according to the json information, but this has to be dynamic. The json information can be different, ie it's dynamic, so how can I render this?
Try this:
in your server.js pass data to index.handlebars file:
res.render(__dirname + "/index.handlebars",{data})
and in index.handlebars use this
<center>
<div class="table">
<table cellspacing="0">
<thead>
<tr class="indices">
<th>Nome</th>
<th>Email</th>
<th>Data de Criação</th>
<th>Convidada de</th>
<th>Codico usado</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{{#each data}}
<tr>
<th scope="row">{{this.id}}</th>
<td>{{this.nome}}</td>
<td>{{this.email}}</td>
<td>{{this.nome_bonus}}</td>
<td>{{this.cod_bonus}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</center>

dynamic V-for shows no result (Vue.js)

I'm trying to fill an array with a list of objects that comes from an api, the objects are coming normally, but when trying to move to the array and play in the v-for nothing appears.
Here's my data vars:
data() {
return {
elementsReport: [],
};
},
Here's my "computed" section:
computed: {
changeElements: {
get() {
return this.elementsReport;
},
set() {
return this.elementsReport;
}
}
}
Here's my api call:
this.elementsReport = this.getHistoryDeliveryPositionsByDriverIdAndDateAPI();
Here's my api function:
getHistoryDeliveryPositionsByDriverIdAndDateAPI() {
axios
.post("/web-api/reports/history-delivery-position/generate", {
driver_id: this.driver,
initial_date: this.initialDate,
final_date: this.finalDate
})
.then(({ data }) => {
_this.elementsReport = data;
})
.catch(function() {
alert("Erro ao filtrar relatórios");
});
}
Here's my html table with the v-for:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
</tr>
</thead>
<tbody>
<tr v-for="elements in changeElements">
<td scope="row">{{elements.id}}</td>
<td></td>
</tr>
</tbody>
</table>
Have you tried to bind the key prop to the tr element?
Like this:
<tr v-for="elements in elementsReport" :key="elements.id">
<td scope="row">{{elements.id}}</td>
<td></td>
</tr>
Lots of things wrong with your code. I would recommend using tutorials to learn JavaScript and Vue.
1) There is no need for a computed here. Use elementsReport in the template.
<tr v-for="elements in elementsReport" :key="elements.id">
<td scope="row">{{elements.id}}</td>
<td></td>
</tr>
2) Your API function is wrong, and you are trying to set elementsReport twice. It should be:
getHistoryDeliveryPositionsByDriverIdAndDateAPI() {
return axios
.post("/web-api/reports/history-delivery-position/generate", {
driver_id: this.driver,
initial_date: this.initialDate,
final_date: this.finalDate
})
.then(({ data }) => {
return data;
})
.catch(function() {
alert("Erro ao filtrar relatórios");
});
}
3) Call it like:
this.getHistoryDeliveryPositionsByDriverIdAndDateAPI().then(data => {
this.elementsReport = data;
});

Displaying multiple jsons in VUE

So this is my code
<script>
export default {
name: "app",
data() {
return {
items: []
};
},
created: function() {
this.makeAjaxCall("books.json", "get").then(res => {
this.items = res
return res
}),
this.makeAjaxCall("authors.json", "get").then(resA => {
this.items = resA
return resA
})
},
methods: {
makeAjaxCall:function(url, methodType){
var promiseObj = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open(methodType, url, true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status === 200){
//alert("xhr done ok");
var response = xhr.responseText;
var respJson = JSON.parse(response);
resolve(respJson);
} else {
reject(xhr.status);
//alert("xhr failed");
}
} else {
//alert("xhr processing");
}
}
//alert("request sent succesfully");
});
return promiseObj;
}
}
};
</script>
<template>
<div id="app">
<table class="booksTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
<th>Availability</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.books" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img id="imageBook" :src="item.imageUrl"></td>
</tr>
</tbody>
</table>
</div>
</template>
I have the function makeAjaxCall that brings me the books.json, but I want to use it for multiple jsons.
I tried to call it under created, with a different json, authors.json, but it doesn't work.
I guess the syntax is wrong.
I know the function could have been created better, but I would like to keep its initial form or maybe add a parameter to be the json file.(Tried that, but didn't work for me)
Any ideas, pretty please?
To bind the data you have to declare first items: {books:[],authors:[]}
Also you are overwriting this.items use this.items.books and this.items.authors to assign.
Below is the example which works without ajax
new Vue ({
el: "#app",
data() {
return {
items: {books:[],authors:[]}
};
},
created: function() {
this.items.books = this.makeAjaxCall("books", "get");
this.items.authors = this.makeAjaxCall("authors", "get");
},
methods: {
makeAjaxCall:function(url, methodType){
if(url == 'books'){
promiseObj= [{name:'name11',author:'author11',genre:'genre11'},{name:'name12',author:'author12',genre:'genre12'}]
}else{
promiseObj= [{name:'name22',author:'author22',genre:'genre22'}]
}
return promiseObj;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.js"></script>
<div id="app">
<table class="booksTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.books" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img :src="item.imageUrl"></td>
</tr>
</tbody>
</table>
<table class="authorsTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.authors" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img :src="item.imageUrl"></td>
</tr>
</tbody>
</table>
</div>
So I found the answer, after millions of tries and it's pretty simple.
<script>
import './styling.scss'
export default {
name: "app",
data() {
return {
items: {books:[], authors:[]}
};
},
created: function() {
this.makeAjaxCall("books.json", "get").then(res => {
this.items.books = res.books;
return res;
}),
this.makeAjaxCall("authors.json", "get").then(res => {
this.items.authors = res.authors;
return res;
})
},
methods: {
makeAjaxCall:function(url, methodType){
var promiseObj = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open(methodType, url, true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status === 200){
//alert("xhr done ok");
var response = xhr.responseText;
var respJson = JSON.parse(response);
resolve(respJson);
} else {
reject(xhr.status);
//alert("xhr failed");
}
} else {
//alert("xhr processing");
}
}
//alert("request sent succesfully");
});
return promiseObj;
}
}
};
</script>
<template>
<div id="app">
<table class="booksTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
<th>Availability</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.books" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img id="imageBook" :src="item.imageUrl"></td>
<td>
<button class="btn add"> Add</button>
<button class="btn edit"> Edit</button>
<button class="btn delete"> Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>