unable to display data using fetch API - node.js - node.js

So, I am getting the below error,
inspected via google chrome
What I am trying to achieve is to explore the Fetch Api by retrieving some data via userApi.js file which pulls it from a srcServer.js (I have hardcoded some data here). I am using webpack bundle and index is the entry point of my project. I have created index.html to bind the data via innerhtml.
Earlier I was using import 'isomorphic-fetch' in my userApi.js file but that too didn't help and hence I found some suggestions on google to use isomorphic-fetch, node-fetch etc. nothing of that sort worked.
I have added most of the artifacts below can you please guide me what is that I am missing here.
Project Structure
userApi.js
import 'isomorphic-fetch'
import 'es6-promise'
export function getUsers () {
return get('users')
}
function get (url) {
return fetch(url).then(onSuccess, onError) //eslint-disable-line
}
function onSuccess (response) {
return response.json()
}
function onError (error) {
console.log(error)
}
index.js
/* eslint-disable */ // --> OFF
import './index.css'
import {getUsers} from './api/userApi'
// Populate table of users via API call.
getUsers().then(result => {
let usersBody = ''
result.forEach(element => {
usersBody+= `<tr>
<td><a href='#' data-id='${user.id}' class='deleteUser'>Delete</a></td>
<td>${user.id}</td>
<td>${user.firstName}</td>
<td>${user.lastName}</td>
</tr>` //eslint-disable-line
})
global.document.getElementById('users').innerHTML = usersBody
})
index.html
<!DOCTYPE <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Users</h1>
<table>
<thead>
<th> </th>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
</thead>
<tbody id="users">
</tbody>
</table>
<script src="bundle.js"></script>
</body>
</html>
srcServer.js
// sample api call data
app.get('/users', function (req, res) {
// Hard coded for simplicity
res.json([
{ 'id': 1, 'firstName': 'P', 'lastName': 'K' },
{ 'id': 2, 'firstName': 'M', 'lastName': 'K' },
{ 'id': 3, 'firstName': 'S', 'lastName': 'K' }
])
})

The error is giving you the exact reason, i.e. user is not defined. Have you tried to print console.log(element); in your forEach loop? You will see what you need to change.
You are accessing the user information incorrectly. In your forEach loop, each value is represented as element not user
result.forEach(element => {
usersBody+= `<tr>
<td><a href='#' data-id='${element.id}' class='deleteUser'>Delete</a></td>
<td>${element.id}</td>
<td>${element.firstName}</td>
<td>${element.lastName}</td>
</tr>` //eslint-disable-line
})

Related

socket with python flask and ajax call

I have scenario where I want to use sockets to wrap my API calls and not available to hit directly the api in browser and get data.
index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.min.css"/>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.html5.min.js"></script>
</head>
<body style="background-color:mintcream;">
<div ><span style="font-family: sans-serif;font-size: x-large;al:center;">reportyu</span> <br> <br>
<table id="example" class="table table-striped table-bordered" style="width:100%;">
<thead>
<tr>
<th>Lame</th>
<th>IAr</th>
<th>Hee</th>
<th>ED</th>
<th>SPs</th>
<th>Ts</th>
<th>SD</th>
<th>Rs</th>
<th>Ld</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Lame</th>
<th>IAr</th>
<th>Hee</th>
<th>ED</th>
<th>SPs</th>
<th>Ts</th>
<th>SD</th>
<th>Rs</th>
<th>Ld</th>
</tr>
</tfoot>
</table>
<script>
function setupData() {
$(document).ready(function () {
$('#example').DataTable({
responsive: true,
"ajax": {
"url": "/index_get_data",
"dataType": "json",
"dataSrc": "data",
"contentType":"application/json"
},
"columns": [
{"data": "L_name"},
{"data": "Ia_r"},
{"data": "He_e"},
{"data": "e_d",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='//abc.app.com/"+oData.e_d+"'>"+oData.e_d+"</a>");
}
},
{"data": "s_ps"},
{"data": "t_s"},
{"data": "s_d",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='//app2.com/"+oData.s_d+"'>"+oData.s_d+"</a>");
}
},
{"data": "R_n",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='//sshse.com/"+oData.R_n+"'>"+oData.R_n+"</a>");
}
},
{"data": "l_d"}
],
dom: 'Bfrtip',
buttons: [
{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'LEGAL'
},
'copyHtml5',
'excelHtml5'
]
});
});
}
$( window ).on( "load", setupData );
</script>
</body>
</html>
here is my app.py :
from flask import Flask, render_template, jsonify
import json
app = Flask(__name__)
#app.route('/index')
#app.route('/')
def index():
return render_template('index.html')
#app.route('/index_get_data')
def stuff():
# Assume data comes from somewhere else
with open('crtp.json') as test_file:
data = json.load(test_file)
return jsonify(data)
if __name__ == '__main__':
app.run()
This works as expected but when I hit the url localhost:5000 in browser I am also able to see the API call in network tab of the browser and then if I hit the endpoint localhost:5000/index_get_data
I am able to use the API openly.
I have explored options of sending token based auth in headers and basic auth but still the response can be derived and the API is still open for use which I want to restrict , I came across flask-sockets which seems to help here but not sure how can I implement this here.
Any help regarding this or any other approach to achieve this would be great.
It isn't clear what you really are trying to do, and why you don't want 'browsers' to be able to see your endpoints. Flask (and browsers) use HTTP and HTTPS to communicate. There are huge amounts of information, packages, etc about how all that works - and if you are interested in any sort of interoperability - you should stick to well-established protocols. You might be asking how to SECURE your endpoints such that only clients that have appropriate credentials can access your site. That is what packages such as Flask-Security-Too, Flask-Dance, Flask-Login all provide. Flask itself doesn't provide any endpoint protection

No styles are added when rendering the page

I have a problem with styles when rendering a page.
There are no problems connecting styles on any other page
This is pug with product.pug:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="styles/main.css">
<title>#{product.product_name}</title>
</head>
<body>
<header>
include layout/menu.pug
include layout/myProfile.pug
</header>
<main>
| there will be data about the product
</main>
include layout/footer.pug
</body>
</html>
This is code with app.js:
app.get('/product/:productId', (req, res) => {
if (req.params["productId"] !== undefined &&
req.params["productId"] > 0) {
conn.query(`SELECT *
FROM product
WHERE product_id = ${req.params["productId"]}`, (err, product) => {
if(err) {throw err;}
if(product.length > 0) {
res.render('product', {
userName: req.session.userName,
successAuthentication: req.session.successAuthentication,
isWorker: req.session.isWorker,
product
})
} else {
res.sendStatus(404);
}
});
} else {
res.sendStatus(404);
}
});
Styles are stored in the public folder, and app is used to use styles
app.use(express.static (path.join(__dirname, 'public')));
Any other page doesn't have a problem with styles.
I can't solve this problem, so I will be grateful for any hint
You can set your express static folder like this code below:
app.use(expresss.static('public'));
Now, you can try to create your public folder in your app root and move your styles folder into your public folder and its Will working fine.
I hope it can help you.

Node.js and Express handlebars - 404 Error

For my class I have to design an app that says at the top of the page whether an incoming request is GET or POST, then has to print a table that shows all parameter names and values that were sent in the URL query string, and the property names and values that were received in the request body.
So far I have been able to get my localhost:port to work, it correctly shows whether a request is GET or POST. But when I go to the subpage that is supposed to display the tables, I get a 404 instead.
Here is the render page that I think is causing the problem:
function runQ(req) {
console.log(req.qParams);
console.log(req.body);
var context = {};
context.queryParams = [];
context.bodyParams = [];
context.queryCount = 0;
context.bodyCount = 0;
for( var p in req.qParams) {
context.queryCount++;
context.queryParams.push({'name': p, 'value': req.qParams[p] });
}
for( var p in req.body) {
context.bodyCount++;
context.bodyParams.push({'name': p, 'value': req.body[p] });
}
context.methodType = req.method;
return context;
}
app.get('/request', function(req, res) {
res.render('request', runQ(req));
});
app.post('/request', function(req, res) {
res.render('request', runQ(req));
});
I have a request.handlebar saved in my ubuntu/getpost/views folder along with the 404 and 500 handlebars.
The command I use for testing is:
$ curl --data "a=1&b=2&c=3" localhost:port
I replaced the localhost:port with an actual IP and port address when I have node running.
My console returns this on the tab that is running node:
undefined
{ a: '1', b: '2', c: '3' }
And this on the tab where I typed the cURL command:
<!doctype html>
<html>
<head>
<title>Demo Page</title>
</head>
<body>
<h1>POST Request Received</h1>
<table>
<caption><p>Request Body Table</p></caption>
<thead>
<tr>
<th>Property Names</th>
<th>Values</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td>1</td>
</tr>
<tr>
<td>b</td>
<td>2</td>
</tr>
<tr>
<td>c</td>
<td>3</td>
</tr>
</tbody>
</table>
</body>
So everything seems to be working from the console but when I try to access localhost:port/request, I go to the 404 error instead of a page that displays the tables.
Can anyone tell me what I'm doing wrong? Thank you all for your time.

How to pass an array in hogan-express template engine

How do I pass an array like the below to a HTML page using hogan-express? I am trying but it doesn't seem to be working.
My code:
apiRouter.get('/myPosts', function(req, res, next){
userModel.findOne({'profileID':req.session.facebookProfileId}, function(err, userPosts) {
if(userPosts) {
res.render('myPosts', {title:siteName + ': My Posts', posts:userPosts.posts});
} else {
console.log('You do not have any posts');
}
})
})
By the way, the userPosts.posts looks like the below:
["123","124","125"]
myPosts.html page is as below:
<!doctype html>
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
</head>
<body>
<p>Post 1</p>
<p>Post 2</p>
</body>
</html>
By the way, the {{title}} bit is coming through.
In short: you can't, at least not like that.
What you can do is iterate over the posts:
{{#posts}}
<p>Post 1</p>
{{/posts}}
However, that would leave you with the problem of the text content for each link ("Post 1"). To fix that, you need to process the array server-side, before you pass it to render.
For example:
res.render('myPosts', {
title : siteName + ': My Posts',
posts : userPosts.posts.map(function(postId, idx) {
return { postId : postId, postNum : 1 + idx };
})
});
And the template:
{{#posts}}
<p>Post {{postNum}}</p>
{{/posts}}
The rendered HTML will look like this:
<p>Post 1</p>
<p>Post 2</p>
<p>Post 3</p>

parsing strange html with node.js

I am trying parse a site, but the html is a mess. Can anyone with more experience in parsing sites help me?
<tr>
<td><font FACE=Tahoma color='#CC0000' size=2><b>Date</b></font></td>
<td><font FACE=Tahoma color='#CC0000' size=2><b>Place</b></font></td>
<td><font FACE=Tahoma color='#CC0000' size=2><b>Situation</b></font></td>
</tr>
<tr><td rowspan=2>16/09/2011 10:11</td><td>New York</td><td><FONT COLOR="000000">Situation Red</font></td></tr>
<tr><td colspan=2>Optional comment hello new york</td></tr>
<tr><td rowspan=2>16/09/2011 10:08</td><td>Texas</td><td><FONT COLOR="000000">Situation Green</font></td></tr>
<tr><td colspan=2>Optional comment hello texas </td></tr>
<tr><td rowspan=1>06/09/2011 13:14</td><td>California</td><td><FONT COLOR="000000">Yellow Situation</font></td></tr>
</TABLE>
A strange and crazy thing is the comment not in the head of table also the start point(california) dont have comment. So, start point always will be like this:
Date: 06/09/2011 13:14
Place: California
Situation: Yellow Situation
Comment: null
all others places have a comment and will be like this:
Date: 16/09/2011 10:11
Place: New York
Situation: Situation Red
Comment: Optional comment hello new york.
I have tried some approaches, but I don't have much experience with node.js and less with HTML parsing. I need a getting started with parsing crazy stuff.
I built a distributed scraper in node.js. I found it easier to parse html that had been parsed through html tidy.
Here is a module to run html through tidy:
var spawn = require('child_process').spawn;
var fs = require('fs');
var tidy = (function() {
this.html = function(str, callback) {
var buffer = '';
var error = '';
if (!callback) {
throw new Error('No callback provided for tidy.html');
}
var ptidy = spawn(
'tidy',
[
'--quiet',
'y',
'--force-output',
'y',
'--bare',
'y',
'--break-before-br',
'y',
'--hide-comments',
'y',
'--output-xhtml',
'y',
'--fix-uri',
'y',
'--wrap',
'0'
]);
ptidy.stdout.on('data', function (data) {
buffer += data;
});
ptidy.stderr.on('data', function (data) {
error += data;
});
ptidy.on('exit', function (code) {
//fs.writeFileSync('last_tidy.html', buffer, 'binary');
callback(buffer);
});
ptidy.stdin.write(str);
ptidy.stdin.end();
}
return this;
})();
module.exports = tidy;
Example (if saved as tidy.js):
require('./tidy.js');
tidy.html('<table><tr><td>badly formatted html</tr>', function(html) { console.log(html); });
Result:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy for Linux/x86 (vers 25 March 2009), see www.w3.org" />
<title></title>
</head>
<body>
<table>
<tr>
<td>badly formatted html</td>
</tr>
</table>
</body>
</html>

Resources