post method from API express & angular 10 - node.js

I'm trying to do a post method with angular and express.js to do that I created a file called index.js where I added different method but in my front end in Angular I would like to simply add data, how to do with reactive forms ?
I followed several tutorials but I did my best
thank you.
index.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
const parkings = require('../parkings.json');
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(express.json());
// Get all parkings details
app.get('/parkings', (req, res) => {
res.status(200).json(parkings)
});
// Get parkings by id
app.get('/parkings/:id', (req, res) => {
const id = parseInt(req.params.id)
const parking = parkings.find(parking => parking.id === id)
res.status(200).json(parking)
});
// post
app.post('/parkings', (req, res) => {
parkings.push(req.body)
res.status(200).json(parkings)
})
app.listen(3000, () => {
console.log("Listening to port 3000");
})
service
url: string = ('http://localhost:3000');
parkingForm = new FormGroup({
name: new FormControl(),
type: new FormControl(),
city: new FormControl()
});
array: any [];
constructor(private http: HttpClient) { }
get(): Observable<any> {
return this.http.get<any>(`${this.url}/parkings`);
}
postMethod() {
let myFormData = new FormData();
myFormData.append('name', this.parkingForm.value.name);
myFormData.append('type', this.parkingForm.value.type);
myFormData.append('city', this.parkingForm.value.city);
return this.http.post(this.url, myFormData,
{ responseType: 'text' }).subscribe(
(response) => this.array.push(response),
(error) => console.log(error)
);
}
ts.file
export class AppComponent implements OnInit {
getTab: any = [];
constructor(private parkingsService: ParkingsService) {}
ngOnInit() {
this.parkingsService.get().subscribe(data => {
this.getTab = data;
})
};
add() {
this.parkingsService.postMethod();
}
}
html
<table>
<tr>
<th>name</th>
<th>type</th>
<th>ville</th>
</tr>
<tr *ngFor="let parking of getTab">
<td>{{parking.name}}</td>
<td>{{parking.type}}</td>
<td>{{parking.city}}</td>
</tr>
</table>
<form [formGroup]="parkingForm">
<div class="form-group">
<input type="text" placeholder="enter name" name="name" formControlName="name"><br>
<input type="text" placeholder="enter type" name="type" formControlName="type"><br>
<input type="text" placeholder="enter city" name="city" formControlName="city"><br>
<button (click)="add()">Ajouter</button>
</div>
</form>

parkingForm: FormGroup;
this.parkingForm = this.formBuilder.group({
name: ['', [Validators.required]],
type: ['', [Validators.required]],
city: ['', [Validators.required]]
});
constructor(private formBuilder: FormBuilder) { }
ngOnInit(){
}
add() {
let bodyJSON={
name:this.parkingForm.get('name').value,
type:this.parkingForm.get('type').value,
city:this.parkingForm.get('city').value
}
this.parkingsService.postMethod(bodyJSON);
}
postMethod(data) {
let myFormData = new FormData();
myFormData.append('name', data.name);
myFormData.append('type', data.type);
myFormData.append('city', data.city);
return this.http.post(this.url, myFormData,
{ responseType: 'text' }).subscribe(
(response) => this.array.push(response),
(error) => console.log(error)
);
}

Related

how get data in nodejs received from frontend in reactjs?

I am begineer in reactjs and nodejs, and I think i post data successfully from front end to backend, but now i want to fetch and display received data from frontend in console, but i didnot know how to do it, anyone guide me in this situation? cause when i print something in console like console.log(data) that time it displays some logs in console but i want to display received data in console
demoLogin.js
// this is frontend in reactjs
import React, { Component } from 'react'
import axios from 'axios'
class Login extends Component {
constructor(props) {
super(props)
this.state = {
username:'',
password:''
}
}
usernameHandler=event=>{
this.setState({
username:event.target.value,
})
}
passwordHandler=event=>{
this.setState({
password:event.target.value
})
}
submitHandler=event=>{
let data = {
username: this.state.username,
password: this.state.password,
};
event.preventDefault()
console.log(this.state)
axios.post('http://localhost:8080/note', data,{
headers: {'Content-Type':'application/json'}
})
.then(res => {
console.log(res)
})
}
render() {
const {username, password}=this.state
return (
<div className="custom_wrapper">
<div className="custom_form-wrapper">
<h1>SIGN IN INTO YOUR ACCOUNT</h1>
<form onSubmit={this.submitHandler} >
<div className="custom_username" >
<label htmlFor="username">User Name</label>
<input className='custom_input'
placeholder="example#email.com"
type="text"
name="username"
value={username}
onChange={this.usernameHandler}
/><br></br>
<label htmlFor="password">Password</label>
<input className='custom_input'
placeholder="password"
type="password"
name="password"
value={password}
onChange={this.passwordHandler}
/>
<button type="submit" >Login</button>
</div>
</form>
</div>
</div>
)
}
}
export default Login
server.js
//this is backend in nodejs
var restify=require('restify')
const corsMiddleware = require('restify-cors-middleware2');
const { data } = require('jquery');
var server=restify.createServer() //server created
server.use(
function crossOrigin(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true); // If needed
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return next();
}
);
const cors = corsMiddleware({
preflightMaxAge: 5, //Optional
origins: ['*'],
allowHeaders: ['*'],
exposeHeaders: ['*']
})
server.pre(cors.preflight)
server.use(cors.actual)
server.use(restify.plugins.bodyParser());
//get data from login form
function userCreation(req, res, next) {
console.log('data received...')
console.log(res.json(data))
return next();
}
server.post('/note', userCreation);
server.listen(8080, function(){
console.log("server started...")
})
Simply create a a GET request to that url you POST ed.
import axios from 'axios'
class App extends Component {
constructor (props) {
super(props)
this.state = {
username: ''
}
this.handleClick = this.handleClick.bind(this)
}
handleClick () {
axios.get('http://localhost:8080/note')
.then(response => this.setState({username: response.data.name}))
}
render () {
return (
<div className='show_my__username'>
<button className='button' onClick={this.handleClick}>Click Me</button>
<p>{this.state.username}</p>
</div>
)
}
}

Network error from using localhost when web app is launched with Netlify

I just deployed a Spotify web app with Netlify. It works fine when it's running on my computer but it doesn't work on others. It shows Network Error, POST http://localhost:4000/search_result net::ERR_CONNECTION_REFUSED. I changed the url of the axios request to "/search_result" but it still didn't work. How should I fix it?
Here's my code.
Main.js
import React, { Component } from "react";
import SingerBox from "./SingerBox";
import axios from "axios";
import "../../App.css";
export class Main extends Component {
constructor(props) {
super(props);
this.state = {
keyword: "",
artists: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({ keyword: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.keyword === "") {
alert("Enter Search Keyword");
}
axios
.post(
"/search_result",
{
keyword: this.state.keyword,
},
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
}
)
.then((res) => {
this.setState({ artists: res.data });
})
.catch((err) => {
console.log(err);
});
}
render() {
return (
<div className="container">
<div className="main">
<form onSubmit={this.handleSubmit}>
<label className="header" htmlFor="search">
Explore New Artists
</label>
<span>
<input
className="search-box"
type="search"
value={this.state.keyword}
onChange={this.handleChange}
name="keyword"
placeholder="Search artists..."
/>
<button className="submit-btn" type="submit" value="Submit">
Search
</button>
</span>
</form>
<br />
{this.state.artists.map((elem) => (
<SingerBox images={elem.images} name={elem.name} id={elem.id} />
))}
<br />
</div>
</div>
);
}
}
export default Main;
server.js
const express = require("express");
const SpotifyWebApi = require("spotify-web-api-node");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const port = 4000 || process.env.PORT;
require("dotenv").config();
app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
// Create the api object with the credentials
var spotifyApi = new SpotifyWebApi({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
});
// Retrieve an access token.
function newToken() {
spotifyApi.clientCredentialsGrant().then(
function (data) {
console.log("The access token expires in " + data.body["expires_in"]);
// Save the access token so that it's used in future calls
spotifyApi.setAccessToken(data.body["access_token"]);
},
function (err) {
console.log("Something went wrong when retrieving an access token", err);
}
);
}
newToken();
tokenRefreshInterval = setInterval(newToken, 1000 * 60 * 60);
app.post("/search_result", (req, res) => {
spotifyApi
.searchArtists(req.body.keyword)
.then(function (data) {
let search_res = data.body.artists.items;
res.json(search_res);
res.end();
})
.catch((err) => {
console.log(err);
res.status(500).send(err);
});
});
app.get("/albums/:id", (req, res) => {
console.log(req.params.id);
spotifyApi
.getArtistAlbums(req.params.id, { limit: 40 })
.then(function (data) {
res.json(data.body.items);
res.end();
});
});
app.get("/albums/tracks/:albumID", (req, res) => {
console.log(req.params.albumID);
spotifyApi
.getAlbumTracks(req.params.albumID, { limit: 20 })
.then(function (data) {
console.log(data.body);
res.json(data.body.items);
res.end();
});
});
app.listen(port, () => console.log(`It's running on port ${port}`));
It is likely that the server code isn't running as you expect it to.
Think about what commands you run to get that localhost server running on your machine, compared to the build command you provided o Netlify to build your site.
Netlify is primarily for hosting static sites, so will not automatically provide a backend server for you to use.
You can either host the server part of your app on something like Heroku (and then have to hard-code the URL of that server instance into your app), or you can use Netlify Functions to handle your basic post request, which will let you use the relative URLs as in your question.

Why is my website running fine on my computer but not on other's?

I made a Spotify web app and launched it with Netlify. When I run its server file, it works well on my computer but not on my friend's. I thought it was because of the Spotify API at first but another web app I made, which doesn't use any API, only works on my computer as well. I think it's because of the server port or something but I'm not sure how to fix it.
Here's the website url and the server side code.
https://xenodochial-kepler-118793.netlify.app
server.js
const express = require("express");
const SpotifyWebApi = require("spotify-web-api-node");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const port = 4000 || process.env.PORT;
require("dotenv").config();
app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
// Create the api object with the credentials
var spotifyApi = new SpotifyWebApi({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
});
// Retrieve an access token.
function newToken() {
spotifyApi.clientCredentialsGrant().then(
function (data) {
console.log("The access token expires in " + data.body["expires_in"]);
// Save the access token so that it's used in future calls
spotifyApi.setAccessToken(data.body["access_token"]);
},
function (err) {
console.log("Something went wrong when retrieving an access token", err);
}
);
}
newToken();
tokenRefreshInterval = setInterval(newToken, 1000 * 60 * 60);
app.post("/search_result", (req, res) => {
spotifyApi
.searchArtists(req.body.keyword)
.then(function (data) {
let search_res = data.body.artists.items;
res.json(search_res);
res.end();
})
.catch((err) => {
console.log(err);
res.status(500).send(err);
});
});
app.get("/albums/:id", (req, res) => {
console.log(req.params.id);
spotifyApi
.getArtistAlbums(req.params.id, { limit: 40 })
.then(function (data) {
res.json(data.body.items);
res.end();
});
});
app.get("/albums/tracks/:albumID", (req, res) => {
console.log(req.params.albumID);
spotifyApi
.getAlbumTracks(req.params.albumID, { limit: 20 })
.then(function (data) {
console.log(data.body);
res.json(data.body.items);
res.end();
});
});
app.listen(port, () => console.log(`It's running on port ${port}`));
Main.js
import React, { Component } from "react";
import SingerBox from "./SingerBox";
import axios from "axios";
import "../../App.css";
export class Main extends Component {
constructor(props) {
super(props);
this.state = {
keyword: "",
artists: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({ keyword: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.keyword === "") {
alert("Enter Search Keyword");
}
axios
.post(
"/search_result",
{
keyword: this.state.keyword,
},
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
}
)
.then((res) => {
this.setState({ artists: res.data });
})
.catch((err) => {
console.log(err);
});
}
render() {
return (
<div className="container">
<div className="main">
<form onSubmit={this.handleSubmit}>
<label className="header" htmlFor="search">
Explore New Artists
</label>
<span>
<input
className="search-box"
type="search"
value={this.state.keyword}
onChange={this.handleChange}
name="keyword"
placeholder="Search artists..."
/>
<button className="submit-btn" type="submit" value="Submit">
Search
</button>
</span>
</form>
<br />
{this.state.artists.map((elem) => (
<SingerBox images={elem.images} name={elem.name} id={elem.id} />
))}
<br />
</div>
</div>
);
}
}
export default Main;
You have hardcoded localhost in your code somewhere. The apis are hitting your local server when someone is searching for the artist.
Remove localhost from code and every thing should work fine.

How do I use data from POST request for the next GET request

I'm trying to build a web app that uses Spotify API now. I want it to send a search keyword that an user submits to the server and send back its search result to the front end. The problem is I get a 404 status code for the fetch call. The POST request works fine.
Main.js
import React, { Component } from "react";
import SingerCard from "./SingerCard";
import axios from "axios";
export class Main extends Component {
constructor(props) {
super(props);
this.state = {
keyword: "",
artists: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({ keyword: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
axios
.post(
"http://localhost:4000/search_result",
{
keyword: this.state.keyword,
},
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
}
)
.then(function (res) {
console.log(res);
})
.catch(function (err) {
console.log(err);
});
}
componentDidMount() {
fetch("http://localhost:4000/api")
.then((res) => res.json)
.then((artists) => {
this.setState({ artists });
});
}
render() {
return (
<div className="main">
<form onSubmit={this.handleSubmit}>
<label htmlFor="search">Search an artist: </label>
<span>
<input
type="search"
value={this.state.keyword}
onChange={this.handleChange}
name="keyword"
/>
<button type="submit" value="Submit">
Search
</button>
</span>
</form>
<br />
<div className="container">
{this.state.artists.map((elem) => (
<SingerCard
images={elem.images}
name={elem.name}
artists={this.state.artists}
/>
))}
{console.log(this.state.artists)}
</div>
<br />
</div>
);
}
}
export default Main;
server.js
const express = require("express");
const SpotifyWebApi = require("spotify-web-api-node");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const port = 4000 || process.env.PORT;
require("dotenv").config();
app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
// Create the api object with the credentials
var spotifyApi = new SpotifyWebApi({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
});
// Retrieve an access token.
spotifyApi.clientCredentialsGrant().then(
function (data) {
console.log("The access token expires in " + data.body["expires_in"]);
console.log("The access token is " + data.body["access_token"]);
// Save the access token so that it's used in future calls
spotifyApi.setAccessToken(data.body["access_token"]);
},
function (err) {
console.log("Something went wrong when retrieving an access token", err);
}
);
app.post("/search_result", (req, res) => {
console.log(req.body.keyword);
spotifyApi.searchArtists(req.body.keyword).then(function (data) {
var search_res = data.body.artists.items;
res.json(search_res);
app.get("http://localhost:/api", (req, res) => {
res.json(search_res);
res.end();
});
res.end();
}),
function (err) {
console.log(err);
};
});
app.listen(port, () => console.log(`It's running on port ${port}`));
I think the app.get() in the app.post() causes the error but I can't figure out another way to send the search result back.
You're getting a 404 because the get method is not correctly defined.
Update your server code to define the get method to just keep the pathname, like this:
app.get("/api", (req, res) => {
// ...
}
Currently, you are defining this route inside the app.post. The get route definition should be outside of the post route.
Use Axios.get
import React, { Component } from "react";
// import SingerCard from "./SingerCard";
import axios from "axios";
export class Main extends Component {
constructor(props) {
super(props);
this.state = {
keyword: "",
artists: []
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({ keyword: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
};
axios.post(
"https://jsonplaceholder.typicode.com/users",
{ keyword: this.state.keyword },
{ headers: headers }
)
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
axios.get("https://jsonplaceholder.typicode.com/users").then(res => {
this.setState({
artists: res.data
});
});
}
render() {
return (
<div className="main">
<form onSubmit={this.handleSubmit}>
<label htmlFor="search">Search an artist: </label>
<span>
<input
type="search"
value={this.state.keyword}
onChange={this.handleChange}
name="keyword"
/>
<button type="submit" value="Submit">
Search
</button>
</span>
</form>
<br />
<div className="container">
{this.state.artists.map(elem => (
<div key={elem.id}>
<ul>
<li>{elem.name}</li>
</ul>
</div>
))}
</div>
</div>
);
}
}
export default Main;

How to parse json response using fetch API

Am trying to display json response after calling an API using fetch, I can see the response in the response tab of chrome, but I can't find it in fetch response object
Client side
import React from 'react';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
query: '',
properties: []
}
this.search = this.search.bind(this);
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const { name, value } = event.target;
// const { query } = this.state.query;
this.setState({
[name]: value
});
}
search() {
console.log('fetching data')
try {
fetch('http://localhost:3000/property/find', {
method: 'POST',
mode: 'CORS',
body: JSON.stringify({ "query": this.state.query }),
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then((data) => {
console.log(data)
this.setState({ properties: data.result });
})
}
catch (err) {
return err;
}
}
render() {
const { properties } = this.state;
return (
<div className="App" >
<input type="text" name="query" onChange={this.handleChange}></input>
<div className="form-group">
<button className="btn btn-primary" onClick={this.search}>Search</button>
</div>
<div className="row text-center">
{properties.items &&
properties.items.map((property, index) =>
<div className="col-lg-3 col-md-6 mb-4" key={index}>
<div className="card h-100">
<img className="card-img-top" src="http://placehold.it/500x325" alt="" />
<div className="card-body">
<h4 className="card-title"> {property.details.description}</h4>
{/* <p className="card-text">{property.biography}</p> */}
</div>
<div className="card-footer">
Find Out More!
</div>
</div>
</div>
)
}
</div>
</div>
)
}
}
export default App;
Server side
var app = express();
const server = http.createServer(app);
const io = socketIo(server);
var db = require('./db');
var property = require('./endpoint/property');
// var authController = require('./auth/AuthController');
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3001');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
next();
});
//allow OPTIONS on just one resource
// app.post('*', cors())
app.use(cors())
app.use('/property', property);
End point response
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: true }));
router.use(bodyParser.json());
var Model = require('../model/propertyModel');
// GETS A SINGLE USER FROM THE DATABASE
router.post('/find',function (req, res) {
var query = req.body.query
console.log(query)
Model.find( { $text: { $search: query }} , { score: { $meta: "textScore" } }).sort( { score: { $meta: "textScore" } } ).then((data)=>{
if(data.length>0){
res.status(200).json({"result":data});
}
if (data.length==0){
Model.find({ "details.description": {$regex:query} }).sort( { score: { $meta: "textScore" } } ).then((data)=>{
if(data){
res.status(200).json({"result":data});
}
if (data.length==0) return res.status(404).send("No properties found.");
})
}
})
});
Inside your render method, if you change this:
{properties.items &&
properties.items.map((property, index) =>
...to this:
{properties &&
properties.map((property, index) =>
That should resolve this for you.
Within the render method, it looks like properties.items is expected to be an array. But in the network tab response screenshot, the result field inside the JSON response is an array.
Calling this.setState({ properties: data.result }); will lead to properties being the field you should be mapping over in the render method, instead of properties.items

Resources