I have a form in ReactJS and every time i click the submit button, the data should pass to adonis api.
ReactJs file
async handleSubmit(e) {
e.preventDefault();
console.log(JSON.stringify(this.state));
await axios({
method: 'post',
url: 'http://127.0.0.1:3333/add',
data: JSON.stringify(this.state),
})
.then(function (response) {
console.log('response',response);
})
.catch(function (error) {
console.log('error',error);
});
}
"http://127.0.0.1:3333/add" is Adonis server with a route '/add'
i don't know how to write in Adonis to post state on that route
Can anybody explain me, please?
in controller's function in get value like this
const data = request.only(['data']) then you get data.
other method to get data like this
const alldata = request.all()
this console this result and view how many result you get
and get data from this alldata.data
First, create a simple controller to handle your data which would receive from your handleSubmit() method in ReactJS app.
Use the below command to create a simple controller:
adonis make:controller TestController --type http
Once created, open the TestController file and make an index method and add the followings which are inside the index method.
'use strict'
class TestController{
// define your index method here
index ({ request }) {
const body = request.post() // get all the post data;
console.log(body) //console it to see the passed data
}
}
module.exports = TestController
After that, register your /add route in start/routes.js file.
Route.post('/add', 'TestController.index') // controller name and the method
And finally, hit the Submit button in your ReactJS app, and test it.
Most likely you be getting CORS issues when you send the request
from your ReactJS app to Adonis server, If so you have to proxy the api request to Adonis server.
To do that, open up your package.json file in ReactJS App, and add the below proxy field.
"proxy": "http://127.0.0.1:3333",
Related
I'm developing a Laravel + Angular app and i'm getting 401 Unauthorized in only 1 GET request.
Here I explain how I developed my authentication and how it work on Backend and Frontend. I wish you can help me.
I use Laravel Sanctum for manage authentication in my app. Here is how I program the backend.
I get users from my BD table:
Note: I have created a separate controller, to separate the authentication functions from the user functions, even so, I have tried to put this function in my AuthController and it has not given me any result.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
class UsersController extends Controller
{
public function getAllUsers()
{
return User::all();
}
}
As I want you to only be able to retrieve all the DB users if you are authenticated, in my api.php file I put the path inside the middleware:
Route::middleware('auth:sanctum')->group(function()
{
Route::post('logout', [\App\Http\Controllers\AuthController::class, 'logout']);
Route::get('getAuthUser', [\App\Http\Controllers\AuthController::class, 'getAuthUser']);
//Admin actions
Route::post('createUser', [\App\Http\Controllers\AuthController::class, 'createUser']);
Route::get('getAllUsers', [\App\Http\Controllers\UsersController::class, 'getAllUsers']);
});
If I make the request from the Postman everything works correctly, if I am not authenticated it gives me an error and if I have previously authenticated it returns all the DB users just as I expected. By the way, I am using cookies to send the jwt to the Frontend.
The problem is when in my Angular app I request my backend with the GET method to retrieve these users and display them in a table. In addition, the code to retrieve the users is within a condition in which it is looking at whether the user is authenticated or not. The truth is that I do not understand what may be happening.
getUsers(): void
{
//Check if user is authenticated
this.http.get('http://localhost:8000/api/getAuthUser', { withCredentials: true }). subscribe(
(res: any) =>
{
Emitters.authEmitter.emit(true);
Emitters.roleEmitter.emit(res.role);
//Get all users
this.http.get('http://127.0.0.1:8000/api/getAllUsers', { withCredentials: true }). subscribe(
res =>
{
this.users = res;
}
)
},
err =>
{
Emitters.authEmitter.emit(false);
Emitters.roleEmitter.emit("none");
alert("You should be authenticated for this.");
}
);
}
The first request that you see above getAuthUser, makes the request to the Backend in the same way as the second request getAllUsers and the first one works perfectly and the second one does not, it is in which I get an err. I call the getUsers() method in the ngInit().
I hope I have explained myself well. Any information you need to know let me know. Thank you.
The solution was in the request that gave the error to change the path of the api, instead of putting 127.0.0.1 putting localhost.
In my vue frontend I have the following method:
methods:{
async moveToOrder() {
const res = await this.$axios.get('/product/cart-to-order', {
headers: {
Authorization: 'Bearer ' + this.userData.userToken
}
});
if (res.status === 200) {
this.$router.push({name: 'Orders'});
}
}
}
The above method hits the following method that moves the data from cart collection to orders collection in the node backend and returns the moved data from orders collection:
exports.cartToOrder = async (req, res, next) => {
///method code goes here
res.status(200).json({products: products});
}
I want to display the data that I get as response in my orders (view or route). Can I pass data returned from backend to next route in Vue ?
Or do I need to make seperate methods on frontend and backend to fetch the data from orders collection ??
You can use query or url parameters between routes with the vue router. However, the data is now exposed in the url and you will now inherit all limitations from url requirements such as length and type (url encoded string).
A couple solutions are more applicable for your issue :
As you mentioned you could trigger a subsequent request if the first call is successful.
Emit the data to the destination view/route (note that the data can only flow up or down the component tree)
(Preferred) Use a state management tool like vuex to centralize your data. You will only need to update (mutate) your data (state) once and it will be available anywhere within your application. The time investment for this solution is not negligeable, however on a longer term it can simplify your application significantly.
I am trying to post form data from angular to node.js. The angular post request sends an empty body.
this is my post router
submit function is ts file
onSubmit( loginData ) {
if(!loginData) { return; }
this.userService.addUser( loginData as User )
.subscribe(user => {
this.users.push(user);
});
service used to post data
addUser(user: User): Observable<User> {
// console.log('this is '+user.email);
const url = `${this.usersUrl}/register`;
return this.http.post<User>(url, user).pipe(
tap((newUser: User) => this.log(`added user w/ email=${newUser.email}`)),
catchError(this.handleError<User>('addUser'))
);
}
Please check once by adding the debug whether the loginData is getting passed in the service or not.
If you don't know how to add debug point simply just print the data using console.log(user)
in the method addUser() as the first line.
And if not getting data then simply modify the method call by:
this.userService.addUser(loginData).subscribe(user => {
this.users.push(user);
});
I figured out the problem.
There is no problem in this angular code.
I also checked the network tab as suggested by David, and saw that the payload was being sent.
the problem was this line of code in my node.js server
app.use(express.static('public'))
Instead I had to use
app.use(exrpess.json())
I had copied the template from another application and somehow missed this. Anyway thanks for all your help!
I created a "user" named model with base class "User". I'm trying to login a user in Angular App using lb-ng generated service but it's not logging in.
In my Login controller I invoked User.login() providing email and password but its giving some weird error.
Even I included this code in my app.js
// Use a custom auth header instead of the default 'Authorization'
LoopBackResourceProvider.setAuthHeader('X-Access-Token');
// Change the URL where to access the LoopBack REST API server
LoopBackResourceProvider.setUrlBase('http://.../api');
In loginController
console.log(User.login({ email: "shah.khokhar#hotmail.com", password: "12345" }));
But it's giving this validation error:
Kindly help me on this.
Thanks,
If you could post your user.json file and your actual angular code then it would be more clear. But as far as I can see, there are things you are doing wrong.
You are making a request to User model instead of your custom user model which obviously won't work as your user data is present in your custom model and not the built in User model
You are most probably making a POST request to a wrong method than login method as login method request url looks something like this
http://localhost:3000/api/users/login
Here's a working sample code for login function which I use for my project
self.login = function () {
var data = {
email: self.email,
password: self.password
};
users.login(data).$promise
.then(function (user) {
$state.go('home');
})
.catch(function (err) {
$state.go('auth.register');
});
};
Hope this helps.
I requested stormpath user custom data by using
res.render('home', {
title: 'home',
user: req.user.customData,
});
i expected to receive a json object of custom data but instead a url ('https://api.stormpath.com/v1/accounts/WvtGbIH3kJ4rEttVF5r9U/customData') was returned. This page does have the custom data i want on it but i cannot request it using an ajax request as it is a https page. What should I do? Thanks in advance
You'll need to use the "auto expansion" feature of the library, like this:
app.use(stormpath.init(app, {
expandCustomData: true,
});
That will expand the custom data resource for you. By default it's just a link to the resource, as you've seen.
Found the best way to request custom data is to use the getCustomData() method in the route, set the data to a variable and use a get request from the client to request this data as in the sample below:
Server Js
customData = new Array;
router.get("/string", function(req, res) {
req.user.getCustomData(function(err, data) {
customData = data.someKey;
})
res.send(customData) /*Returns Empty Arrray*/
})
router.get("/cdata", function(req, res) {
res.send(customData) /*Sends Actual Custom Data*/
})
Client Js
var customData = new array
$(document).ready(function() {
$.get("/string", function(string) {
/*Tells server to get customData*/
})
$(document).click(function(){
if(pleaseCount===0){
$.get("/cdata", function(data) {
for(i=0;i<data.length;i++){
customData.unshift(data[i])
pleaseCount=pleaseCount+1
/*Custom data is now stored in client side array*/
}
})
}
})
That's what worked for me anyway. I don't know why someone down-voted the question as this is an acceptable way to retrieve other user information such as name and email by using userName:req.user.userName in the render function and rendering this information to a p. tag in a jade page by using p #{userName}