Getting JSON Object when the page is reloaded - mysql

I made an angular application and I made a NodeJS API which is running on different port from the angular application. I made a call to the API and displayed the returned JSON data on the gallery component which is a routed component. But when I reloaded the page I am only seeing my JSON data written but no gallery component. How can this be fixed? Thanks in advance!
This is my gallery component ts file.
import { DbConnectService } from '../db-connect.service';
interface GalleryItem {
path : String
}
#Component({
selector: 'app-gallery',
templateUrl: './gallery.component.html',
styleUrls: ['./gallery.component.css']
})
export class GalleryComponent implements OnInit {
galleryitem:any;
p:any = 1;
count: any = 2;
constructor(private gallery : DbConnectService) {
this.gallery.getgallery().subscribe((galleryitems) =>{
this.galleryitem= galleryitems;
})
}
ngOnInit(){
}
}
This is my API file
const bodyparser = require("body-parser")
const express = require("express");
const app = express();
const mysql = require("mysql");
app.use(bodyparser.json());
const conn = mysql.createConnection({
host:"localhost",
user:"root",
password:"",
database:"youngshoulders_gallery"
})
conn.connect((err)=>{
if(err) throw err;
console.log("mysql connected");
})
app.get("/gallery",(req,res)=>{
let sql = "SELECT * FROM GALLERY";
let query = conn.query(sql,(err,result)=>{
if(err) throw err;
res.send(result);
})
})
app.listen(8000);
This is the data returned when API is called
OUTPUT WHEN API IS CALLED
This is the returned JSON data after reloading the above page
JSON Output when page reloaded

Related

Why can't send form-data in postman

Trying to send form-data in postman and sequelize return error:
value cannot be null
But when send raw request with json all ok. Trying body-parser and multer, but nothing working
This is my index.ts
import express from "express";
import fileUpload from "express-fileupload"
...
const app = express()
const PORT = process.env.PORT || 5100
app.use(cors())
app.use(express.json())
app.use('/api', router)
app.use(fileUpload({}))
app.use(errorHandler)
const start = async () => {
try {
await sequelize.authenticate()
await sequelize.sync()
console.log(chalk.cyanBright('Successful conection to data base'));
app.listen(PORT, () => { console.log(chalk.cyanBright(`Server has been started on port ${PORT}`)) })
}
catch (e) {
console.log(e);
}
}
start()
And this is my controller
export const DeviceController = {
async create(req: Request, res: Response, next:nextType) {
try {
const { brandId, typeId, name, price } = req.body
const img = req.files
let filename = 'uuid.v4()' + '.jpg'
img?.mv(path.resolve(__dirname, '..', 'static', filename))
const device = await Models.Device.create({ brandId, typeId, name, price, img: filename })
return res.json(device)
} catch (error: any) {
next(ApiError.badRequest(error.message))
console.log(error);
}
app.use(express.json())
You have body parsing middleware for JSON request bodies.
You don't have body parsing middleware for multipart/form-data request bodies. The documentation for body-parser lists a several middlewares you could use.
Trying body-parser
… which says it doesn't support that format
and multart
… that doesn't appear to exist. Do you mean multiparty? Or maybe multer?
We can't tell you what you did wrong without seeing your attempt.
Re edit:
You said:
const img = req.files
img?.mv(path.resolve(__dirname, '..', 'static', filename))
But the documentation says:
console.log(req.files.foo); // the uploaded file object
The files property contains all the files, indexed by the the names given to them in the multipart request.
You're trying to read that collection of files as if it were a single file.

Vue CRUD using NodeJs (MySql conncetion) - How do I get the data from server-side to client-side?

I'm trying to learn more about Vue and to make it interesting I have connected to my MySql-DB using nodeJS.
By following a tutorial (https://webdeasy.de/en/complete-login-system-with-node-js-vue-js-restapi-jwt-part-1-2/) I have a working Login system. Now I want to fetch some data from another table (the table called 'clients') and make a simple CRUD, but I do not understand how to get the data from the Server-side(node-js) to the Client-side(Vue).
I got a connection working where I can output my table data in the console.log - And I know I have use Axios (pointing to localhost:3000 where my server is running) to make it work, but everything I have tried either crashes my app or just doesn't work.
My router.js filer (Server-side) looks like this (I didn't paste all the login 'stuff' to keep clean for you):
// routes/router.js
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const uuid = require('uuid');
const jwt = require('jsonwebtoken');
const db = require('../lib/db.js');
const userMiddleware = require('../middleware/users.js');
// All the login code is here
// All the login code is here
// All the login code is here
db.query
("SELECT * FROM clients", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
module.exports = router;
Which correctly returns this in the console.log:
[nodemon] starting `node Server`
The server running on port 3000
[
RowDataPacket {
id: 1,
name: 'Sample Client One',
email: 'email-one#domain.com',
phone: '12345678'
},
RowDataPacket {
id: 3,
name: 'Sample Client two',
email: 'mail-two#domain.com',
phone: '12345678'
}
My Clients.vue looks like this now:
<template>
<div>
<h1>Hi {{ username }}, Welcome to Clients</h1>
<p>{{ secretMessage }}</p>
</div>
</template>
<script>
import AuthService from '#/services/AuthService.js';
export default {
data() {
return {
secretMessage: 'Sample secret message',
username: '',
};
},
async created() {
if (!this.$store.getters.isLoggedIn) {
this.$router.push('/login');
}
this.username = this.$store.getters.getUser.username;
this.secretMessage = await AuthService.getSecretContent();
},
methods: {
logout() {
this.$store.dispatch('logout');
this.$router.push('/login');
}
}
};
</script>
I have Axios installed, I just removed the import of it to avoid the error.
As you probably can see a am new at this so let me know if going about this all wrong or if you need to see more of my code.
//Rue
Make sure that you are fetching the clients from an CRUD endpoint.
For instance, you can add a new /clients endpoint where you read all the clients then return them back to client-side with res.status(200).send(result), as follows:
router.get('/clients', (req, res, next) => {
db.query("SELECT * FROM clients", function (err, result, fields) {
if (err) {
res.status(400).send();
throw err;
};
console.log(result);
res.status(200).send(result);
});
});
And your client-side code now needs to fetch data from server-side. One can create a new file ClientServices.js under services/ folder, like so
// src/services/ClientServices.js
import axios from 'axios';
const url = 'http://localhost:3000/api/';
export default {
getClients() {
return axios
.get(url + 'clients/')
.then(response => response.data);
}
};
The UI code now needs to import the new file and call getClients method and list them.
<template>
<div>
<h1>Hi {{ username }}, Welcome to Clients</h1>
<p>{{ secretMessage }}</p>
</div>
<div :key="client.id" v-for="client in clients">
<strong>client.name</strong>
<small>client.email</small> | <small>client.phone</small>
</div>
</template>
<script>
import AuthService from '#/services/AuthService.js';
import ClientService from '#/services/ClientService.js';
export default {
data() {
return {
secretMessage: 'Sample secret message',
username: '',
clients: [],
};
},
async created() {
if (!this.$store.getters.isLoggedIn) {
this.$router.push('/login');
}
this.username = this.$store.getters.getUser.username;
this.secretMessage = await AuthService.getSecretContent();
var self = this
ClientService.getClients().then((clients) => {
self.clients = clients;
});
},
methods: {
logout() {
this.$store.dispatch('logout');
this.$router.push('/login');
}
}
};
</script>

How to save rendered html view files from ExpressJS Routes

I've built few pages of a static website using ExpressJS and PUG to get the advantage of the template engine.
But now I need to export all the raw HTML that is being rendered by all ExpressJS Routes.
Is there any package that can help me to do that? Or I've to write custom command and iterate over all the Routes and save the rendered output?
If a custom command is the only way, how do I iterate over all the routes and get the rendered output?
I couldn't find any library or resource to achieve what I wanted. But with some of my dirty code, hacks, and packages I was able to export all the routes.
Note: Instead of writing a node command to export the htmls, I've added a route to trigger the operations here is the code for the route:
app.use('/export_templates', router.get('/', async function (req, res, next) {
const endpoints = listEndpoints(app);
const failedEndpoints = [];
for (const i in endpoints) {
const endpoint = endpoints[i];
if (endpoint.path == '/export_templates') {
continue;
}
try {
const res = await axios.get('http://'+req.headers.host+''+endpoint.path+'?export=true');
}
catch(error) {
failedEndpoints.push(endpoint.path);
}
}
res.json({
"status": "succes",
"message": "Please check templates folder for the latest exported html templates",
"failed": failedEndpoints
})
}));
Basically this route iterates and makes a request to all the available routes with a export=true parameter.
Then inside every route view function a condition checks if the export parameter is available then calls the exportTemplateFile function with the pug template location and new file name as the function parameter.
If the request doesn't contain export parameter the requested route will simply output what template.
An example route:
router.get('/', function(req, res, next) {
if (req.query.export) {
exportTemplateFile('views/index.pug', 'index.html');
}
res.render('index.pug');
});
And here is the code for 2 util function to complete the export process
function createTemplateFile(filename) {
fs.open(filename,'r',function(err, fd){
if (err) {
fs.writeFile(filename, '', function(err) {
if(err) {
console.log(err);
}
});
}
});
}
function exportTemplateFile(templateLocation, templateName) {
const html = pretty(pug.renderFile(templateLocation));
createTemplateFile('templates/'+templateName);
var stream = fs.createWriteStream('templates/'+templateName);
stream.once('open', function (fd) {
stream.write(html);
stream.end();
});
}
The createTemplateFile function simply creates a new file if it doesn't exist.
The exportTemplateFile function saves the HTML in the html variable rendered by pug and prettifies it with the pretty package and then overwrites the new template file.
Note: In my case all the pug templates were static so I didn't have to pass any context to the pug.renderFile function. But if you need any context to be used inside the pug template you can simply pass that with the template location.
Edited version of the same answer.
First of all thank you so much for solving this problem.
I have made some changes to your code as per new errors.
Here is the code with async and await function for ejs users
const express = require('express')
const ejs = require('ejs')
const fs = require('fs')
const app = express()
const port = 3000
//set the templating engine as ejs
app.set('view engine', 'ejs');
function createTemplateFile(filename) {
fs.open(filename,'r',function(err, fd){
if (err) {
fs.writeFile(filename, '', function(err) {
if(err) {
console.log(err);
}
});
}
});
}
async function exportTemplateFile(templateLocation, templateName) {
var html = await ejs.renderFile(templateLocation);
createTemplateFile('templates/'+templateName);
var stream = fs.createWriteStream('templates/'+templateName);
stream.once('open', function (fd) {
stream.write(`${html}`);
stream.end();
});
}
app.get('/', (req, res, next) => {
res.render('./pages/home')
exportTemplateFile('views/pages/home.ejs', 'index.html');
console.log('file rendered and saved successfully')
})
app.listen(port, () => {
console.log(`App is listening on port ${port}`)
})

How to interface JSON data and display table

So I am trying to display a list of devices from the database into an angular material table. I've written the REST api for it which is something like this:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const mysql = require('mysql');
//parse application/json
app.use(bodyParser.json());
//create database connection
const conn = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'project'
});
//connect to database
conn.connect((err) =>{
if(err) throw err;
console.log('Mysql connected....');
});
//server listening
app.listen(3000,() =>{
console.log('Server started on port 3000');
});
//show login page
app.use(express.static(__dirname+'/dashboard'))
app.get('/',(req,res) => {
res.send('Use /api/devices');
});
//show all devices
app.get('/api/devices',(req,res) => {
let sql = "SELECT * FROM tempstatus";
let query = conn.query(sql, (err, results) => {
if(err) throw err;
res.send(JSON.stringify({'status': 200, 'error': null, 'response': results}));
});
});
And now I have written a controller as follows:
var myApp = angular.module('myApp', [require('angular-material-data-table')]);
myApp.controller('DeviceController', function($scope, $http){
console.log('DeviceController loaded')
$scope.getDevices = function(){
var device = null;
$http.get('/api/devices').success(function(response) {
device = response;
});
}
}
I'm rather new to Angular and nodejs and I don't really know how what else I must do and how to display the data I get in an angular material table. Can you please help me out?
This is the JSON data I'm getting from the API:
"status":200,"error":null,"response": {"serialnum":"0","time":"2020-02-11T12:36:27.000Z","type":"","temparature":"","date":"2020-02-10T18:30:00.000Z","status":"not active","comments":""}
And this is the angular.module.ts file. As I said, I'm new to angular and I don't know how to write my code. So far I've only done this and the controller in angular:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

fetch JSON array from node to Reactjs

I'm trying to fetch an array on my node server on localhost:3000/users to my react app on localhost:3000.
The problem is I don't getting an array on react and cannot fetch anything to my list.
var express = require('express');
var router = express.Router();
var arr = [{
id: 1,
username: "samsepi0l"
}, {
id: 2,
username: "D0loresH4ze"
}];
/* GET users listing. */
router.get('/', function(req, res, next) {
// Comment out this line:
//res.send('respond with a resource');
// And insert something like this instead:
res.json(arr);
});
module.exports = router;
And the react App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
state = {users: []}
componentDidMount() {
fetch("/users")
.then( (res) => res.json())
.then( (json) => {this.setState({users: json});});
}
render() {
return (
<div className="App">
<h1>Users</h1>
{this.state.users.map(user =>
<div key={user.id}>{user.username}</div>
)}
</div>
);
}
}
export default App;
How can I fetch the array to react page?
and here is the error that I got when I run the npm server:
Unhandled Rejection (SyntaxError): Unexpected token < in JSON at position 0
You should implement the endpoint for the fetch("/users") call
router.get('/users', function(req, res, next) {
console.log('got the response');
res.json(arr);
});
Also, you need to separate your front end react app from your server express which handles the request.
You cannot have the same port which your apps are listening. Set up different port. I.E 8000 for the front end and 8080 for the express server
UPDATE
I've managed to reproduced the tutorial which i think is the same you have found based from here : https://medium.com/front-end-hacking/calling-express-api-in-react-using-react-script-e19084a76a8a
There is nothing wrong with the tutorial. You have to set up the proxy part in the client/package-json
"proxy" : "http://localhost:3005"
and in the bin/www you have to set the line from
var port = normalizePort(process.env.PORT || '3000');
to
var port = normalizePort(process.env.PORT || '3005');
finally you may need to install the concurrently dependency in the server package.json
finally i have attached the tree structure of the tutorial