Express delete-route not working with angular applications - node.js

Somehow Delete (and put/patch) routes never work. they work fine when testing with postman but never when called from my angular applications.
//calling delete route from angular application. this does not work
DeleteDay(){
this.http.delete("http://192.168.1.102:3000/api/5f7a391013cbd02ea001fb82");
}
//delete route from server
router.delete('/:postId', async (req, res) => {
try{
const removedPost = await Dag.findByIdAndDelete({ _id: req.params.postId });
res.json(removedPost);
} catch(err) {
res.json({ message: err });
}
});
//calling delete using postman. this DOES work
screen from postman

When the HttpClient makes HTTP requests, it returns an Observable which needs to be subscribed. The same may work on postman but while using it in angular, you need to subscribe to it in the following way:
import {HttpClient} from '#angular/common/http';
constructor(private http:HttpClient){}
//your function
DeleteDay(id:string){
console.log("id could be made dynamic",id);//5f7a391013cbd02ea001fb82
this.http.delete("http://192.168.1.102:3000/api/"+id)
.subscribe((data)=>{
console.log(data); //data will actually be an Object sent from Express
})
}
PS: I have changed your function to work even on dynamic IDs, use it as per your need.

Related

How to call an external API from my API in Koa.js

I have an issue where I want to call an external API to verify a certain token coming from my frontend.
i.e
router.post('/api/verifyToken', async (ctx, next) => {
router.post('https://external-site.com/verify').then((response) => {
if (response.success) { console.log('Do some stuff') };
})
})
How would I go about doing this with koa?
You misunderstood with the router itself.
In your router, you define a route where your clients can send HTTP requests and according to your business logic, you return the answers to them.
You can simply imagine router.post('/api/verifyToken' as an event listener. When a request comes in you run whatever is inside of it. It is not an HTTP client though.
If you want to send an external request you have to use an HTTP client for it.
There are a bunch of options:
Built-in http/https package
Axios
Node-fetch
GOT
Request
And many others
One simple example how to do with Axios would be
import axios from 'axios';
router.post('/api/verifyToken', async (ctx, next) => {
try{
const response = await axios.post('https://external-site.com/verify');
// Do your stuff here
console.log(response.data);
ctx.body = response.data;
}catch(e){
ctx.status = 422;
ctx.body = e.message;
}
})

"JWT Must be provided " error - When trying to access an endpoint in my deployed server written in Node.js Typescript

Libs used in the BE: coockie parser, cors, jwt, bcrypt and express.
I am running into the JWT must be provided error. This happens when I am trying to access some of the endpoints it in the fronted in React and i am making the the fetch call from localhost:300.
I have looked at my backend logic to make sure everything adds up, but i can spot any evident bugs.
any hits or suggestions would be greatly appreciated it:
below is the controllers code and the ensure auth code.enter image description here
const theTransactions = Router();
theTransactions.post('/makeTransaction', ensureAuth, async (req: Request,
res:Response, next: NextFunction)=>{
try {
const newTransaction = await
TransactionServices.createTransaction({sender_id:req.user.id,...req.body});
console.log('BODY',req.body);
res.send(newTransaction);
} catch (error) {
next(error);
}
});
theTransactions.get('/searchrecipient/:email', ensureAuth ,async (req:Request,
res:Response, next: NextFunction)=>{
try {
const searchedRecipient = await User.findByEmail(req.params.email);
res.send(searchedRecipient)
} catch (error) {
next(error);
}
});
export default theTransactions

JSON array from Express route is undefined in React console

I am currently working on a web app to manage an external database. I am not very familiar with express or NodeJS at this point so I wanted to ask how to send a JSON object to the client sides console without getting undefined?
I have this function to connect then select the what I need and afterwards I converted my JSON object to an array of JSON objects. It displays the data fine in the console as well.
async function connect() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (err) {
console.error('Unable to connect to the database:', error);
}
info = await sequelize.query('select * from LeadsInformation', { type: QueryTypes.SELECT });
const details = JSON.stringify(info);
console.log(details);
detailsArray = JSON.parse(details);
console.log(detailsArray);
}
Everything works fine in here, I can get the data and display it in the terminal.
This is my GET route:
app.get("/list", (req, res) => {
connect();
res.json(detailsArray)
});
I have tried a couple of suggested ways based on other explanations and code snippets but none of them has worked so far so I left it like that. I thought foreaching through the data itself in the request would be a solution but it did not work. I also tried using the JSON itself and trying to display it and also tried using the body parser library. Though the library has not been updated for two years. Also I am using axios to fetch the data. It works fine when I try sending a simple string like "hello world" for example.
Is there anything that I'm missing or do you have any other solutions? I would also appreciate an explanation as well if possible.
Edit: It might also have to do something with how I am getting the response in the frontend. I'll look into that as well and will update this thread if I sort it out!
This is the way I get the response. I am currently trying to show in the console. I am using axios API.
Axios({
method: "GET",
url: "http://localhost:5000/list",
headers: {
"Content-Type": "application/json"
}
}).then(res => {
console.log(res.data.json);
});
Probably you have undefined in route because connect function doesn't return anything.
Also connect is an async function it means that it returns Promise and you have to call .then method or use await to get value from it.
Here is the code snippet with fixes that I described above.
async function connect() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (err) {
console.error('Unable to connect to the database:', error);
}
info = await sequelize.query('select * from LeadsInformation', { type: QueryTypes.SELECT });
const details = JSON.stringify(info);
detailsArray = JSON.parse(details);
return detailsArray;
}
app.get("/list", async (req, res) => {
const result = await connect();
res.json(result)
});
Notice that in the router handler function I also use async and await because I call connect which is an asynchronous function.
The solution above did work and also another problem I had was that I wasn't getting the response correctly.
I ended up getting the response to the frontend after changing my code to the following from:
console.log(res.data.json);
To:
console.log(res.data[1]);

Node server is unable to process data send with axios get and returns different error than postman

I am using node js server on my local environment, I have tested the APIs with postman and it is working as expected. Now I am working on creating front-end with the help on react js. I am having trouble with Axios.get method with parameters. As it is not returning the same error as it does with postman. I am sending data in x-www-form-urlencoded in postman , and this is what i am trying to achieve with Axios in react js.
let config = {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
params: {
eth_wallet: this.state.deposit_address
},
}
axios.get(methods.verify_eth_transaction, config)
.then((result)=>{
console.log(result)
})
.catch((err)=>{
console.log(err)
})
I have also tried
axios.get(methods.verify_eth_transaction, qs.stringify(this.state.deposit_address), config)
.then((result)=>{
console.log(result)
})
.catch((err)=>{
console.log(err)
})
It should return "Unable to find a deposit. Please try again." as it is in postman get call.
But it is returning "Wallet not found", making me believe that there is something wrong with the way i am sending parameters in my request.
And this is how my node server use the parameters.
Bridge.find({ eth_wallet: { $in: req.body.eth_wallet } }, (err, account) => {
//
//
})
Axios GET method doesnt take a body object. You can either change your API route to use POST method or you can change the way you are sending your params like this:
axios.get(url, {
params: {
eth_wallet: this.state.deposit_address
}
});
Hope this helps!!

How does my https.post function know which function to call from API

My service file, which sends/gets data from mongoDB:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { filter, isEmpty, map } from 'rxjs/operators';
import { Employee } from './employee';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
uri = 'http://localhost:4000/employees';
data: Employee[];
addEmployee(empObj) {
this.http.post(`${this.uri}`, empObj).subscribe(res => { console.log('Done') })
alert('Done adding data');
}
getEmployees(): Observable<Object> {
return this.http.get(`${this.uri}`)
}
getEmployee(id: number): any {
return this.http.get('https://api.myjson.com/bins/mpg19')
}
deleteEmployee(id: number) {
console.log('ID of employee to be deleted', id);
return this.http.get(`${this.uri}/delete/${id}`);
}
}
And here is my file that performs CRUD operations.
const express = require('express');
const app = express();
const employeeRoute = express.Router();
let Employees = require('../models/Employee');
employeeRoute.route('/').post(function (req, res) {
console.log('coming here', req.body)
let employee = new Employees(req.body);
console.log('data to save is: ', employee)
employee.save().then(employee => { res.status(200).json({ 'employee': 'Employee added in successfully' }) })
})
employeeRoute.route('/').get(function (req, res) {
console.log('Employees Fetched');
let employees = [];
Employees.find({}, function (err, results) {
if (err) {
console.log(err);
}
else {
employees = results;
res.json(employees);
}
})
})
employeeRoute.route('/delete/:id').get(function (req, res) {
console.log('Delete Function Called')
Employees.findByIdAndRemove({ id: req.params.id }), function (err, Employees) {
console.log('Id against which employee is deleted: ', id);
if (err) res.json(err);
else res.json('Successfully removed');
}
});
module.exports = employeeRoute
My application is getting and fetching the data properly, as I was following a written tutorial, I have a little confusion understanding the code. and that is:
how does my addEmployee(empObj) function (in first file) knows which function to call from the CRUD file.
Thanks is advance.
There are a couple of things here you need to become more familiar with.
HTTP Server vs HTTP Client
Your HTTP Client is responsible for sending HTTP(s) requests to a server. When it dispatches this request, it usually has no way of knowing whether the server a) will accept the request or, b) what the server will do with the request. Therefore, when you call http.post(), your HTTP Client does not know what your server will do with that request. You can think of this as a message that your http client sends to a server with some instructions and details.
Your HTTP Server is responsible for accepting, validating and routing incoming requests as well as responding to those requests. Your server alone knows how it wants to handle incoming requests, and whether it will accept or deny them (or at least this is how it should be.)
You can learn more about how HTTP works here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview
REST
Just as your HTTP Client doesn't have any way of knowing what your server will do with a particular HTTP Request, so to are you (the developer) unable to easily reason with your HTTP Server and all of it's potentially valuable data. It is for this reason that REST aims to establish a set of principles designed around structuring content (or resources) on the internet, with reasonable ways of describing these resources and easy ways address these resources with common English Verbs (GET, PUT, DELETE, POST, etc... ).
You can read more about REST (and find related links) here: https://developer.mozilla.org/en-US/docs/Glossary/REST
Express Routing
Express acts as a software routing layer on your HTTP server. It's important to understand that this means express is responsible for creating and registering virtual routes on your server that point to resources. For example, when you do: http.post('http://myserver.com/api/employees'); you are actually asking express (in this example) to try and find a registered route with the route path of 'api/employees' and respond with a resource (or resources) where appropriate.
Therefore, to answer your question directly - Angular's HTTP Client does not know which function will be run on your Express HTTP Server. Your Express Server uses the route http://localhost:4000/employees to determine what kind of resource you're asking for. In this case, it looks for a route registered to 'employees' and validates whether that route accepts the POSTs. If it does accept POSTs, then it executes the callback associated with that registered route.

Resources