How to fetch data from mongodb in MERN - mongodb

I got a problem while getting information from db to frontend in MEAN Stack.
i've try using axios plugin to fetch data, but nothing show.
this is the code:
and this is my data in mongodb:
how can i show the information to this part (ex: for username)?
<div className="user-details">
<tr>
<th>Username: </th>
<th></th>
</tr>
</div>

I am not sure about what is your problem exactly is, you set user as an array, but in render method you treat as a "text", try to iterate over each user by using map method and show each individual users information, if you have problem getting information from your API, try to set proxy in client-side package.json, to API port, and use actions in reacts ComponentDidMount lifecycle.

You can use like below, Add header to your axios request, set 'crossDomain': true to overcome cors errorr.
export default class Profile extends Component{
constructor(props){
super(props);
this.state = {
users: []
}
}
conmponentDidMount(){
axios.get('/api/account/profile',{ headers: { 'crossDomain': true, 'Content-Type': 'application/json' } })
.then(res=> {
this.setState({ users: res.data }).then(profileState => {
console.log(JSON.stringify(this.state.users))
}); //It sets the state asynchronously
})
}
render(){
<div>
<div className="user-details">
{
this.state.users.map(user =>
<tr>
<td>Username: </td>
<td>{user.name}</td>
</tr>
)
}
</div>
</div>
}
}

thanks,
actually i just used this.state.user.name without maping to show from database
<strong>Name:</strong>{this.state.user.name}<br/>
and in api i get the user id in url to get current user/active user from session.
axios.get('/api/account/profile/info?id=' +id)
.then(res => {
this.setState({ user: res.data.user });
})

Related

How To Properly Initialize Form Data In Vue

so I have a component that is rendering a form and it also is pre-filling the fields with data received from ajax request.
My issue is that I want to not only be able to edit fields but also add new fields to submit at the same time, so because of this I am trying to initialize my pre-filled data and new data into the same Object to be submitted with my ajax request. With my current set up the form-data is not consistently filling in the fields before the form is rendered.
This is the form template
<form #submit.prevent="editThisWorkflow" class="d-flex-column justify-content-center" >
<div>
<input type="text" v-model="workflowData.workflow">
</div>
<div >
<div v-for="object in workflowData.statuses" :key="object.id">
<input type="text" v-model="object.status">
</div>
<div v-for="(status, index) in workflowData.newStatuses" :key="index">
<input type="text" placeholder="Add Status" v-model="status.value">
<button type="button" #click="deleteField(index)">X</button>
</div>
<button type="button" #click="addField">
New Status Field
</button>
</div>
<div>
<div>
<button type="submit">Save</button>
<router-link :to="{ path: '/administrator/workflows'}" >Cancel</router-link>
</div>
</div>
</form>
This is the script
data() {
return {
workflowData: {
id: this.$store.state.workflow.id,
workflow: this.$store.state.workflow.workflow,
statuses: this.$store.state.workflow.statuses,
newStatuses: []
},
workflowLoaded: false
}
},
computed: {
...mapGetters(['workflow']),
},
methods: {
...mapActions(['editWorkflow']),
editThisWorkflow() {
this.editWorkflow({
id: this.workflowData.id,
workflow: this.workflowData.workflow,
statuses: this.workflowData.statuses,
newStatuses: this.workflowData.newStatuses
})
},
addField() {
this.workflowData.newStatuses.push({ value: ''});
},
deleteField(index) {
this.workflowData.newStatuses.splice(index, 1);
}
And this is the store method to submit the data
editWorkflow(context, workflowData) {
axios.patch('/workflowstatuses/' + workflowData.id, {
workflow: workflowData.workflow,
statuses: workflowData.statuses,
newStatuses: workflowData.newStatuses
})
.then(response => {
context.commit('editWorkflow', response.data)
})
.catch(error => {
console.log(error.response.data)
})
},
My problem comes in here
data() {
return {
workflowData: {
id: this.$store.state.workflow.id,
workflow: this.$store.state.workflow.workflow,
statuses: this.$store.state.workflow.statuses,
newStatuses: []
},
workflowLoaded: false
}
},
Is there a better way to set this part??
workflowData: {
id: this.$store.state.workflow.id,
workflow: this.$store.state.workflow.workflow,
statuses: this.$store.state.workflow.statuses,
newStatuses: []
},
If you only need to assign store values to your form once then you can use mounted function.
mounted: function() {
this.id = this.$store.state.workflow.id
this.workflow = this.$store.state.workflow.workflow
this.statuses = this.$store.state.workflow.statuses
},
data() {
return {
workflowData: {
id: '',
workflow: '',
statuses: '',
newStatuses: []
},
workflowLoaded: false
}
},
the data property does not accept this, I usually use arrow function in this question because it prohibits me from using this, and prohibits my team from also using this within the data.
Declare all necessary items within the datato maintain reactivity, and assign the value within the mounted of the page.
mounted() {
this.workflowData.id = this.$store.state.workflow.id
this.workflowData.workflow = this.$store.state.workflow.workflow
this.workflowData.statuses = this.$store.state.workflow.statuses
},
data: () => ({
workflowData: {
id: '',
workflow: '',
statuses: '',
newStatuses: []
},
workflowLoaded: false
}
},
})
The way how I resolved this problem turned out to be simpler than most of the solutions presented here. I found it hard to reach data from this.$store.state due to Vuejs life cycle. And assigning values to v-mode tourned out to be impossible because "v-model will ignore the initial value, checked or selected attributes found on any form elements. It will always treat the Vue instance data as the source of truth."
Solution
To pre-fill the field with data received from ajax request e.g. input field of type email I did as follow.
1st. I saved the output of my ajax request in application's storage (Cookies) -it can be Local Storage or Session, depended what is appropriate to you.
2nd. I populated my Vuex's store (single source of truth) with the data from my application storage. I do it every time when I reload a page.
3rd. Instead of binding a data to v-model in Vuejs life cycle, or using value attribute of html input (<input type="email" value="email#example.com">). I Pre-filled input by populating placeholder attribute of html with data coming from Vuex store like this:
<input v-model="form.input.email" type="email" name="email" v-bind:placeholder="store.state.user.data.email">

React|Rest API: Storing form data into an object on the REST API

I've set up a react web application that's currently listing all "Employees" from a mongodb.
I'm now trying to "add" employees to the database through a react frontend form.
I've managed to pass the data from the form to the application but I'm unsure of the process I need to go through to actually get that data solidified into an object and stored in the api.
Please excuse my code, it's disgusting as this is my first week learning react(honestly with little js knowledge, that's another story) and I've just patched together like 20 tutorials....
Here's my Form class:
class Form extends React.Component {
state = {
fullname: '',
}
change = e => {
this.setState({
[e.target.name]: e.target.value
});
}
onSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.state)
this.setState({
fullname: ''
})
}
render() {
return <div>
<form>
<input name="fullname" placeholder="Full Name" value={this.state.fullname} onChange={e => this.change(e)} />
<button onClick={e => this.onSubmit(e)}>Submit</button>
</form>
</div>
}
}
and my Listing(?) class:
class EmployeeList extends React.Component {
constructor(props) {
super(props);
this.state = {employee: []};
this.EmployeeList = this.EmployeeList.bind(this)
this.componentDidMount = this.componentDidMount.bind(this)
}
componentDidMount() {
this.EmployeeList();
}
EmployeeList() {
fetch('/api/employees').then(function(data){
return data.json();
}).then( json => {
this.setState({
employee: json
});
console.log(json);
});
}
onSubmit = fields => {
console.log('app component got: ', fields)
}
render() {
//return a mapped array of employees
const employees = this.state.employee.map((item, i) => {
return <div className="row">
<span className="col-sm-6">{item.fullname}</span>
<span className="col-sm-2" id={item.action1}></span>
<span className="col-sm-2" id={item.action2}></span>
<span className="col-sm-2" id={item.action3}></span>
</div>
});
return <div>
<Form onSubmit={fields => this.onSubmit(fields)}/>
<div className="container">
<div className="row">
<div className="col-sm-6 bg-warning"><h3>Full Name</h3></div>
<div className="col-sm-2 bg-success"><h3>Action 1</h3></div>
<div className="col-sm-2 bg-success"><h3>Action 2</h3></div>
<div className="col-sm-2 bg-success"><h3>Action 3</h3></div>
</div>
</div>
<div id="layout-content" className="layout-content-wrapper">
<div className="panel-list">{ employees }</div>
</div>
</div>
}
}
I've managed to pass the data to the listing app evident by
onSubmit = fields => {
console.log('app component got: ', fields)
}
But how can I go about making a post request to store this data I send into an object on the db? And then also reload the page so that the new list of all employee's is shown?
Thanks so much for your time!
You can use fetch API to make POST request as well. Second parameter is the config object wherein you can pass the required request configurations.
fetch('url', {
method: 'post',
body: JSON.stringify({
name: fields.fullname
})
})
.then(response) {
response.json();
}
.then( json => {
this.setState({
employee: json
});
});
Additional Request Configs which can be used :
method - GET, POST, PUT, DELETE, HEAD
url - URL of the request
headers - associated Headers object
referrer - referrer of the request
mode - cors, no-cors, same-origin
credentials - should cookies go with the request? omit, same-origin
redirect - follow, error, manual
integrity - subresource integrity value
cache - cache mode (default, reload, no-cache)

Correctly receive data from web API but impossible to display them using Angular2/TypeScript

I'm trying to display the information I receive from a Web API but I think I'm missing something in my component.
The call in the service work (I receive a code 200 with all the Application)
List of the application
But then, I just want to display them in the console and it doesn't fill the table.
ngOnInit(){
this.getApplications();
console.log(this.applications);
}
getApplications() {
this.applications = [];
this._UCCXCiscoService.getApplications().subscribe(
res => {
this.applications = res;
},
error => this.errorMessage = <any>error
);
}
// Model
export interface Application {
self: string;
ScriptApplication: ScriptApplication;
id: string;
applicationName: string;
type: string;
description: string;
maxsession: number;
enabled: string;
}
export interface ScriptApplication {
script: string;
scriptParams: ScriptParam[];
}
export interface ScriptParam {
name: string;
value: string;
type: string;
}
export interface RootObject {
type: string;
application: Application[];
}
My model is good, I'm pretty sure of that. I Think it's the method getApplications() that's wrong, but can't find why...
Thanks in advance for your help,
Florian
EDIT 1 : Code of getApplications() in my service
#Injectable()
export class UCCXCiscoService {
public headers:Headers = new Headers({ 'Content-Type': 'application/json' ,'Authorization': 'Basic User + mdp'});
constructor(private http: Http) {
}
getApplications() {
let options = new RequestOptions({ headers: this.headers });
return this.http.get('API URL', options)
.map(data => <Application[]> data.json().application)
.catch(this.handleError);
}
Yes this method works and returns me the applications (as shown in the picture List of Applications). I didn't put the api url and the password here for privacy reason ^^'
EDIT 2 :
getApplications() of component and the response of the service
EDIT 3 :
<div class="contentPage">
<div class="pageTitleHeaderContainer">
<div class="pageTitle">
<span>Cisco</span>
</div>
</div>
<div class="subContent">
<message-to-user messageToUser={{messageToUser}} messageLevel={{messageLevel}}></message-to-user>
<table class="table table-hover table-condensed">
<th>Id</th>
<th>Nom</th>
<tr *ngFor="#application of applications">
<td>{{application?.id}}</td>
<td>{{application?.applicationName}}</td>
</tr>
</table>
</div>
</div>
Yor are printing on the console in the ngOnInit() method, i.e. before the subscription code is executed and therefore before the applications property is filled.
Move console.log() method inside the arrow function of subscribe() just after this.applications = res;
So thanks to the community, I found my problem. First the console.log() wasn't in the right place. Then I needed to change the ngFor to display the info and now it works fine !
You can read the comment of my post, to find the answer.

AngularJS ignores form submit

I'm using AngularJS v1.2.13 to create a page with a form which will download a user's file on click.
I'm using $sce to enable the injection of the file URL which works fine.
However, the loading of the resource disables the form submit. I'm sure it has to do with the resource load because when I remove the load and hardcode the url it works fine. I've also created a JSFiddle without it and have not been able to reproduce the problem there.
Any ideas on why this is happening and how it can be fixed?
HTML:
<div ng-controller="viewProfileController" data-ng-init="findOne();">
<form method="get" action="{{downloadFileURL}}">
<button type="submit" class="no-button comment-small" >
Download File
</button>
</form>
</div>
Controller:
'use strict';
angular.module('bop.viewProfile').controller('viewProfileController', [
'$scope', 'Users', '$sce', '$routeParams',
function($scope, Users, $sce, $routeParams) {
$scope.downloadFileURL = '';
// Find current user
$scope.findOne = function() {
Users.get({
userId: $routeParams.userId
}, function(user) {
$scope.user = user;
$scope.downloadFileURL = $sce.trustAsResourceUrl($scope.user.file.url);
});
};
}]);
Users Service:
var userServices = angular.module('bop.users', ['ngResource']);
userServices.factory('Users', ['$resource', function($resource) {
return $resource(
'users/:userId',
{ userId: '#_id' },
{ update: { method: 'PUT' } }
);
}]);

knockoutjs mapping select data-bind options

I am having problems binding the selected value of a selectbox to a property within the view model. For some reason it keeps coming back unchanged when posted back to the server.
My Html is:
<form action="/Task/Create" data-bind="submit: save">
<table border="1">
<tr>
<td>ref type</td>
<td><select data-bind="options: ReferenceTypes, optionsText: 'Name', optionsCaption: 'Select...', value:Task.ReferenceTypeId"></select></td>
<td>Reference</td>
<td><input data-bind="value:Task.Reference" /></td>
</tr>
</table>
<button type="submit">Save Listings</button>
</form>
The Javascript is:
<script type="text/javascript">
var viewModel = {};
$.getJSON('/Task/CreateJson', function (result) {
viewModel = ko.mapping.fromJS(result.Data);
viewModel.save = function () {
var data = ko.toJSON(this);
$.ajax({
url: '/Task/Create',
contentType: 'application/json',
type: "POST",
data: data,
dataType: 'json',
success: function (result) {
ko.mapping.updateFromJS(viewModel, result);
}
});
}
ko.applyBindings(viewModel);
});
</script>
JSON from Fiddler that gets loaded into the page as below.
{
"ContentEncoding":null,
"ContentType":null,
"Data":{
"Task":{
"ReferenceTypeId":0,
"Reference":"Default Value"
},
"ReferenceTypes":[
{
"Id":2,
"Name":"A Ref Type"
},
{
"Id":3,
"Name":"B Ref Type"
},
{
"Id":1,
"Name":"C Ref Type"
}
]
},
"JsonRequestBehavior":1
}
This comes back into the server (ASP.NET MVC3) correctly, with the updated Reference string value, but ReferenceTypeId is not bound to the correctly selected drop down value. Do I need to perform any additional functions to bind correctly etc? Or tell the data-bind what the select value column is (Id) etc? I have checked in Fiddler on the values getting posted back from the browser, and it has the same original value (0). So it is definately not the server.
I hope someone can help, if you need any further information please ask.
Kind Regards
Phil
The issue is that your options binding will try to assign the object that it is bound to, to the value observable specified.
For example if you select "A Ref Type" the options binding will push the json object
{ "Id":2, "Name":"A Ref Type" }
Into your Task.ReferenceTypeId observable which will then be serialized back to your server. In this case you need to add an optionsValue config options to tell the binding just to save the id.
<select data-bind="options: ReferenceTypes, optionsText: 'Name',
optionsCaption: 'Select...', optionsValue: 'Id', value:Task.ReferenceTypeId">
</select>
Here's an example.
http://jsfiddle.net/madcapnmckay/Ba5gx/
Hope this helps.