Angular 4 and Nodejs http post request implementation error - javascript

I created small test application using Angular 4 and Nodejs. I want to insert a text field value to the database either Mongo or mysql.
Following files I created server.js for running nodejs, Created server>router folder with another file api.js and Angular 4 user component created.
What i did code shown below
user.component.html
<form (submit)="addHobby(hobbies,hobby.value)">
<input type="text" #hobby>
<input type="submit" value="Submit">
</form>
user.component.ts
addHobby(arrHob,hobby) {
if(arrHob.indexOf(hobby) == -1) {
this.hobbies.unshift(hobby);
this.dataService.postHobby(hobby).subscribe((posts) => {
console.log(posts);
})
}
return false;
}
Services folder contain data.service.ts
postHobby(hobby) {
return this.http.post('/api/insertHobby',hobby).map(res => res.json().data);
}
server router folder contain api.js
router.post('/insertHobby', (req, res) => {
console.log("Welcome to post method");
console.log(req.body.data);
})
When form submitting i'm getting output as only welcome to post method
req.body.data i'm getting as *'Undefined'* How to resolve this issue. Any way thanks to everyone..

since you are not passing the variable as object , you need to pass it in object format as below :
postHobby(hobby) {
return this.http.post('/api/insertHobby',{hobby: hobby}).map(res => res.json().data);
}

Related

Laravel: API not found in production environment

I have created an API called "getservicedata" which returns data to be used in Vue.js component.The problem is I get a 404 status code on my production enviroment, which means the file cannot be found. Locally, this is not an issue, only on the production environment.
api.php file:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::group(['middleware' => 'auth:sanctum'], function(){
// Create new API estimate
Route::apiResource('estimate', EstimateController::class);
// Get Service Data
Route::get('/services/getservicedata', [ServiceController::class, 'getServiceData']);
// Create new API Service
Route::apiResource('services', ServiceController::class);
});
ServiceController file:
public function getServiceData()
{
$services = Service::with('vendor')->get();
return $services;
}
Vue.js component:
methods: {
loadServices: function(){
axios.get('/api/services/getservicedata')
.then(response => {
this.services = response.data;
})
.catch(function(error){
console.log(error);
});
},
Please clear the route cache on the production. Still, you face the issue then check the route list of laravel with the below command and see route exists with which URL.
php artisan route:list
Thanks!

vue + nuxt.js - How to read POST request parameters received from an external request

I have a an external form which submits a post request to my nuxt app. I am struggling currently to find out how I can access these POST request parameters in my nuxt page?
I found so far the "asyncData" method, but when I try to access the submitted parameter through the "params" object it is always "undefined". What do I wrong here?
"asyncData" nuxt reference
example code in my nuxt page, assuming "email" is the request parameter submitted from outside
export default {
asyncData({ params }) {
console.log('asyncData called...' + params.email);
return {email: params.email};
},
external html form
<body>
<form action="https://..." target="_blank" method="post">
<input name="email" class="input" type="text" placeholder="Email" maxlength="255"></input>
<input name="submit" class="btn" type="submit" value="Ok"></input>
</form>
</bod>
I found a way, as described in "asyncData" nuxt reference you can pass the request and response object to the "asyncData({req,res})" call.
Here an example - assuming 'email' is one of the post parameter. querystring is a module of node.js and allows you to parse the request body into an array.
Small Remark - this seems only to work for nuxt page level components but not for lower level components
<script>
export default {
asyncData({ req, res }) {
if (process.server) {
const qs = require('querystring');
var body = '';
var temp = '';
while(temp = req.read()) {
body += temp;
}
var post = qs.parse(body);
return {data: post};
}
},
data() {
return {
data: '',
}
},
mounted() {
console.log(this.data['email']);
},
</script>
Nuxt.js cannot handle such things by itself.
https://nuxtjs.org/api/configuration-servermiddleware
You should implement your own middleware for such cases.
And asyncData has nothing to do with handling inbound POST data.

How can I pass data from Angular to Node.Js server and vice versa by one endpoint?

I have code in Nodejs as backend and Angular as frontend.
I want to receive and send data by one endpoint and based on that data from server toggle a button. Toggling is working now but I want when I sign out from the dashboard next time that I log in I could see the value of the key is based on the value from the database.
For example, first, it's SET after clicking it changed to CLEAR and I sign out from the dashboard. When next time I log in I want to see the CLEAR label on my button.
These are codes for several parts of the app:
Angular Service
this.setUserFeatured = function(id, setFeatured) {
return $http.put('/admin/v2/users/' + id + '/featured', { setFeatured: setFeatured })
.then(returnedDataOrError);
};
Angular Controller
function updateFeaturedButtonLabel() {
$scope.featuredButtonLabel = $scope.user.setFeatured ? "Clear Featured" : "Set Featured";
}
function toggleFeatured () {
$scope.user.setFeatured = !$scope.user.setFeatured;
UserService.setUserFeatured($stateParams.id, $scope.user.setFeatured)
updateFeaturedButtonLabel();
};
Html File
<a class="btn btn-info" ng-click="toggleFeatured()" ng-class="{on:user.setFeatured}">{{featuredButtonLabel}}</a>
Server Controller
function addFeaturedUser(req: $Request, res: $Response, next: NextFunction) {
const schema = Joi.object().keys(_.pick(validate, ['userId', 'setFeatured']));
const queryParams = { userId: req.params.id };
if (!req.params.id) {
return new errors.BadRequest('userId is not specified');
}
return validate.validate(queryParams, schema)
.then(validatedParams =>
userService5.updateUserLabel(validatedParams.userId, req.body.setFeatured))
.then(result => res.json(result))
.catch(next);
}
router.put('/users/:id/featured', addFeaturedUser);
And updateUserLabel is a function that handling the connection to the database and retrieving the data.
I just wonder how can I use the data from the server to change the label of the button?
true/false for the setting the button is coming from the .then(result => res.json(result))
Thanks in advance for help
For your question, I suppose you are asking how to use the response object returned in
$http.put().then(function(response){})
You can find the structure of response object in following document.
https://docs.angularjs.org/api/ng/service/$http
To access the data returned from server:
$http.put().then(function(response){response.data})
which corresponds to what your server sends.
Besides, the toggleFeatured function should be add to $scope object.
Otherwise, ng-click can't trigger that function in html template.
Hope it helps.

Pass input to url parameters in angular 2

I'm trying to pass an input from angular2 to a url parameter on a get request to retrieve data from my database. I've looked everywhere to see if anyone else has done this and while they have passed objects as parameters I'm not sure if that is what I need to do.
here's some code..
This is my backend express route to retrieve data from my mongodb.
app.get('/displayorders/:showOrder', function (req, res) {
db.woocommerceorders.findOne({ id: req.params.showOrders }, function
(err, data) {
if(err){
console.log(err);
}res.send(data);
});
})
This is my service in angular2 to retrieve data from my mongodb.
displayOrders(showOrders) {
var displayedOrders;
return this.http.get('http://localhost:3000/displayorders/:' + showOrders)
.map(res => res.json());
}
This is my front end click event to retrieve the desired parameter from the input and pass it as a parameter on my url string.
onFindOrderById(showOrders) {
this.woocommerceService.displayOrders(showOrders)
.subscribe(
data => this.showOrders = JSON.stringify(data),
error => alert(error),
() => console.log('Displaying Order By Id')
);
}
This is my html used to take the input and pass it to my click event function.
<div class="form-group container bottom-border">
<button type="button" class="btn displaybutton"
(click)="onFindOrderById(showOrders)">Click To Retrieve</button>
<br><br>
<div class="row">
<div class="col-xs-6">
<input class="form-control col-xs-6" [(ngModel)]="showOrders"
placeholder="Input Id Number">
<p><b>Retrieved Order:</b></p> <div>{{showOrders}}</div>
</div>
</div>
</div>
I'm wondering if I should try a post request instead? I feel as though this should be straight forward but right now I keep getting an error of UNEXPECTED END OF JSON ENDPOINT. Any help would be greatly appreciated.

CollectionsFS File is not uploaded to server

i am working myself through the discover meteor project (microscope) and tried to add a file upload, which i wanted to do by CollectionFS. My microscope implementation is quite minimal. I am trying to rebuild a minimal dribbble or Workdesk show and tell website.
I installed:
cfs:standard-packages
cfs:filesystem
cfs:ui
Next I am having a collection called rooms which stores a room with a name, for a user (lib/collections/rooms.js):
Rooms = new Mongo.Collection("rooms");
And a roomImages CollectionFS Collection (lib/collections/roomImages.js):
var imageStore = new FS.Store.FileSystem("roomImageStore", {
path: "upload",
maxTries: 5 //optional, default 5
});
RoomFS = new FS.Collection('roomImages', {
stores: [imageStore],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});
RoomFS.allow({
insert: function () {
return true;
},
update: function () {
return true;
},
remove: function () {
return true;
},
download: function () {
return true;
}
});
As I have removed referencing for reducing the debug effort I have this publications.js
Meteor.publish('rooms', function() {
return Rooms.find();
});
Meteor.publish('singleRoom', function(id) {
check(id, String);
return Rooms.find(id);
});
Meteor.publish('roomImages', function(){
return RoomFS.find();
});
Inserting a room works. After the room initially is created, the user then is routed to the rooms editing page.
<template name="roomEdit">
<form class="main form">
<input name="files" type="file" class="fileUploader" multiple>
{{#each images}}
{{#unless this.isUploaded}}
{{> FS.UploadProgressBar bootstrap=true}}
{{/unless}}
{{/each}}
</form>
</template>
I took the function off the documentation in the readme:
Template.roomEdit.events({
'change .fileUploader': function (event, template) {
FS.Utility.eachFile(event, function(file) {
RoomFS.insert(file, function (err, fileObj) {
//Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
});
});
});
Now in my collections there are
cfs._tempstore.chunks
cfs.roomImages.filerecord
after trying to upload one image (the progress bar is not showing) cfs.roomImages.filerecord has the file as collection item, but the uploads folder keeps being empty, therefore I think the file is not uploaded, also if I don't give a path, the default folder is not generated.
I have already read both documentations (website and github) and tried different examples, but most of them seem to be outdated.
Am I missing something? I have no real idea why the file is not uploaded to the server.
If you have the subscription on the client, try this code.
First on the /lib/collection.js folder declare the FSCollection like this
var imageStore = new FS.Store.FileSystem("roomImageStore", {
path: "upload",
maxTries: 5 //optional, default 5
});
roomImages = new FS.Collection('roomImages', {
stores: [imageStore]
});
And not the Same file subscribe to the FSCollection.
if(Meteor.isClient) {
Meteor.subscribe('RoomFS');
}
Now on the /server/collections.js make the same publish you have.
Meteor.publish('roomImages', function(){
return roomImages.find();
});
roomImages.allow({
insert:function(userId,doc){
if(Meteor.userId()){
return true; //if user is logged we return true
} else{
console.log("some foreign user try to upload a file take care"); //server log
return false
}
}
})
we create and subscribe the FSCollection on the /lib folder.. why? because the lib folder its the firs thing meteor loads, so with that we have the fsCollection available on both server/client.
Now we need to upload a new file, so lets create a example template
First we don't want the file to load when we click "accept" on the file input so lets put a submit file button, so the html looks like this.
on Client/exampleUpload.html
<template name="example">
<div class="form-group">
<label>Upload the Image</label>
<input id="testImage" type="file">
</div>
<button type="submit" id="uploadTest"> Click to upload</button>
</template>
on Client/exampleUpload.js
//events
Template.example.events({
'click #uploadTest':function(){
var file $('#testImage').get(0).files[0] / here we store the file
var fsFile = new fsFile(file); // here we add to the fsFile instance
fsFile.metadata = {
coolTextToImage:"this is a cool text" // here we add some metadata to the fs file
}
if(file === undefined){
alert("IF NOT IMAGE NOT INSER") //here we add some validation
} else{
roomImages.insert(fsFile,function(err,result){
if(err){
console.log(err.reason) // here we check if some error occurs when inserting
} else{
console.log(result) // if everything ok, wee should see a console.log with some like [Fs.file] object
}
})
}
}
})
Edit
I recommend you to use gridFS,check at this gitHub issue and also if you use FSfileSystem on production on each deploy the files will be deleted(i think Modulus.io respect the Path).
How to fix it? use the other 2 adapter gridFs or s3, in my case i use GridFS, and GraphicsMagic Package
So first Install the GM package
meteor add cfs:graphicsmagick
With this package you can control the size, type, etc of the file(image)
And declare the new FsCollection like this
imageStore = new FS.Collection("imageStores", {
stores: [new FS.Store.GridFS("imageStore",{
beforeWrite:function(fileObj){
return {
extension: 'png',
type: 'image/png'
};
},
transformWrite:function(fileObj, readStream, writeStream){
// Aqui la convierte en una imagen segun de 10x10 seguuuun
gm(readStream).resize(400).stream('PNG').pipe(writeStream); //resize depends your needs
}
})]
});
this is just a recommendation if you are planning deploy the app
Tell me if works, GL

Categories

Resources