Pass Parameter on Axios Update Request - node.js

I am trying to pass a MongoDB's ObjectId (_id) as a parameter when making an Axios update request. I have a multi-step form that I am working with; after the first step the users account is created and they are logged in. The update request is made on step 2 of the form, so at this point the user is already authenticated.
My update request is below:
const changeOnClick = e => {
const users = {
shareEmail,
filmmakerQuestion,
genres,
favoriteFilm,
imbd,
portfolio,
aboutYou
};
console.log(users)
axios
.put(`http://localhost:5000/users/update/:id`, users)
.then(res => console.log(res.body))
.catch(err => {
console.log(err);
});
NodeJs Route:
router.put('/update/:id', (req, res) => {
Users.findById(req.params.id)
.then(user => {
user.shareEmail = req.body.shareEmail;
user.filmmakerQuestion = req.body.filmmakerQuestion;
user.genres = req.body.genres;
user.favoriteFilms = req.body.favoriteFilms;
user.imbd = req.body.portfolio;
user.portfolio = req.body.portfolio;
user.aboutYou = req.body.aboutYou
user
.save()
.then(() => res.json("The User is UPDATED succesfully!"))
.catch(err => res.status(400).json(`Error: ${err}`));
})
.catch(err => res.status(400).json(`Error: ${err}`));
});
Form code (step 1):
import React, { useState, useContext } from 'react';
import Exit from '../cancel.svg';
import Modal from 'react-modal';
import { useForm } from "react-hook-form";
// import Register from './Components/register';
import axios from "axios";
// import { Redirect } from 'react-router-dom';
import { useHistory } from "react-router-dom";
import UserContext from "../context/UserContext";
Modal.setAppElement('#root');
const Profile = () => {
const [modalIsOpen, setModalIsOpen] = useState (true);
const { register, handleSubmit, errors } = useForm ();
const [shareEmail, setshareEmail] = useState();
const [filmmakerQuestion, setfilmmakerQuestion] = useState();
const [genres, setgenres] = useState();
const [favoriteFilm, setfavoriteFilm] = useState();
const [imbd, setimbd] = useState();
const [portfolio, setportfolio] = useState();
const [aboutYou, setaboutYou] = useState();
const onSubmit = (data) => console.log(data);
const { userData } = useContext(UserContext);
const history = useHistory();
const changeOnClick = e => {
const users = {
shareEmail,
filmmakerQuestion,
genres,
favoriteFilm,
imbd,
portfolio,
aboutYou
};
console.log(users)
axios
.put(`http://localhost:5000/users/${userData.user.id}`, users)
.then(res => console.log(res.body))
.catch(err => {
console.log(err);
});
history.push("/Landing/ProfilePic")
};
return(
<Modal isOpen={modalIsOpen} onRequestClose={() => setModalIsOpen(false)} className='createBorder'>
<form onSubmit={handleSubmit(changeOnClick)} encType="multipart/form-data" >
<div className='border-bottom'>
<img onClick= {() => setModalIsOpen(false)} src={Exit} className='exitButton-two' alt='X' />
<span className='complete-profile'>Complete your profile</span>
</div>
<div>
<p className='filmmakerQ'>Please mark if your email can be shared with filmmakers:</p>
<div className='shareblock'>
<input onChange={e => setshareEmail(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='shareEmail' value='yes' name="shareEmail"/>
<label htmlFor='shareEmail'>Yes, share my email with filmmakers</label>
</div>
<div className='shareblock'>
<input onChange={e => setshareEmail(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='noShare' value='no' name="shareEmail"/>
<label htmlFor='noShare'>No, do not share my email</label>
</div>
<p className='filmmakerQ'>Are you a filmmaker?</p>
<div className='shareblock'>
<input onChange={e => setfilmmakerQuestion(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='yesFilmmaker' value='yes' name="filmmakerQuestion" />
<label htmlFor='yesFilmmaker'>Yes, I am a filmmaker</label>
</div>
<div className='shareblock'>
<input onChange={e => setfilmmakerQuestion(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='noFilmmaker' value='no' name="filmmakerQuestion" />
<label htmlFor='noFilmmaker'>No, I am not a filmmaker</label>
</div>
<p className='filmmakerQ'>What genres of film do you like? Check all that apply:</p>
<div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='horror' type="checkbox" htmlFor='horror' name="genres" />
<label htmlFor='horror' className='move'>Horror</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='animation' type="checkbox" htmlFor='animation' name="genres" />
<label htmlFor='animation'>Animation</label>
</div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='drama' type="checkbox" name="genres" />
<label htmlFor='drama' className='move'>Drama</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='comedy' type="checkbox" htmlFor='comedy' name="genres" />
<label htmlFor='comedy' className='move'>Comedy</label>
</div>
</div>
<div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='action' type="checkbox" htmlFor='action' name="genres" />
<label htmlFor='action' className='move'>Action</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='documentary' type="checkbox" htmlFor='documentary' name="genres" />
<label htmlFor='documentary'>Documentary</label>
</div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='scifi' type="checkbox" htmlFor='scifi' name="genres" />
<label htmlFor='scifi' className='movemore'>Sci-Fi</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='expriemental' type="checkbox" name="genres" />
<label htmlFor='experimental'>Experimental</label>
</div>
</div>
<p className='filmmakerQ'>What are your favorite films?</p>
<input ref={register({required: false})} onChange={e => setfavoriteFilm(e.target.value)} className='inputsThree' name='favoriteFilm' autoComplete='off'></input>
<p className='minifieldsNew'>These will be shared to your profile.</p>
<p className='filmmakerQ'>Please share a link to your IMBD profile if available:</p>
<input ref={register({required: false})} onChange={e => setimbd(e.target.value)} className='inputsThree' name='imbd' autoComplete='off'></input>
<p className='minifieldsNew'>If you are a filmmaker, our community is very interested to learn more about what projects you have been a part of. This will be shared on your profile</p>
<p className='filmmakerQ'>If you have a link to a portfolio please share below:</p>
<input ref={register({required: false})} onChange={e => setportfolio(e.target.value)} className='inputsThree' name='portfolio' autoComplete='off'></input>
<p className='minifieldsNew'>This is your chance to show your work. This will be shared on your profile</p>
<p className='filmmakerQ'>Anything else you want to share about yourself?</p>
<input ref={register({required: false})} onChange={e => setaboutYou(e.target.value)} className='inputsThree' name='aboutYou' autoComplete='off'></input>
<p className='minifieldsNewNew'>Our community is very interested in learning more about you as a filmmaker</p>
</div>
<div>
<button type='submit' className='signupButton3'>Sign Up</button>
{/* <a onClick={handleSubmit(onSubmit)} type='submit' className='doneButtontwo'>
<span>Done</span>
</a> */}
<div>
<a href='/GetStarted' className='later'>I'll do this later</a>
</div>
</div>
</form>
</Modal>
)
}
export default Profile;
Form code (step 2):
<form onSubmit={handleSubmit(changeOnClick)} encType="multipart/form-data" >
<div className='border-bottom'>
<img onClick= {() => setModalIsOpen(false)} src={Exit} className='exitButton-two' alt='X' />
<span className='complete-profile'>Complete your profile</span>
</div>
<div>
<p className='filmmakerQ'>Please mark if your email can be shared with filmmakers:</p>
<div className='shareblock'>
<input onChange={e => setshareEmail(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='shareEmail' value='yes' name="shareEmail"/>
<label htmlFor='shareEmail'>Yes, share my email with filmmakers</label>
</div>
<div className='shareblock'>
<input onChange={e => setshareEmail(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='noShare' value='no' name="shareEmail"/>
<label htmlFor='noShare'>No, do not share my email</label>
</div>
<p className='filmmakerQ'>Are you a filmmaker?</p>
<div className='shareblock'>
<input onChange={e => setfilmmakerQuestion(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='yesFilmmaker' value='yes' name="filmmakerQuestion" />
<label htmlFor='yesFilmmaker'>Yes, I am a filmmaker</label>
</div>
<div className='shareblock'>
<input onChange={e => setfilmmakerQuestion(e.target.value)} ref={register({required: false})} className='sharePosition' type="radio" htmlFor='noFilmmaker' value='no' name="filmmakerQuestion" />
<label htmlFor='noFilmmaker'>No, I am not a filmmaker</label>
</div>
<p className='filmmakerQ'>What genres of film do you like? Check all that apply:</p>
<div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='horror' type="checkbox" htmlFor='horror' name="genres" />
<label htmlFor='horror' className='move'>Horror</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='animation' type="checkbox" htmlFor='animation' name="genres" />
<label htmlFor='animation'>Animation</label>
</div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='drama' type="checkbox" name="genres" />
<label htmlFor='drama' className='move'>Drama</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='comedy' type="checkbox" htmlFor='comedy' name="genres" />
<label htmlFor='comedy' className='move'>Comedy</label>
</div>
</div>
<div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='action' type="checkbox" htmlFor='action' name="genres" />
<label htmlFor='action' className='move'>Action</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='documentary' type="checkbox" htmlFor='documentary' name="genres" />
<label htmlFor='documentary'>Documentary</label>
</div>
<div className='shareBox'>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='scifi' type="checkbox" htmlFor='scifi' name="genres" />
<label htmlFor='scifi' className='movemore'>Sci-Fi</label>
<input onChange={e => setgenres(e.target.value)} ref={register({required: false})} value='expriemental' type="checkbox" name="genres" />
<label htmlFor='experimental'>Experimental</label>
</div>
</div>
<p className='filmmakerQ'>What are your favorite films?</p>
<input ref={register({required: false})} onChange={e => setfavoriteFilm(e.target.value)} className='inputsThree' name='favoriteFilm' autoComplete='off'></input>
<p className='minifieldsNew'>These will be shared to your profile.</p>
<p className='filmmakerQ'>Please share a link to your IMBD profile if available:</p>
<input ref={register({required: false})} onChange={e => setimbd(e.target.value)} className='inputsThree' name='imbd' autoComplete='off'></input>
<p className='minifieldsNew'>If you are a filmmaker, our community is very interested to learn more about what projects you have been a part of. This will be shared on your profile</p>
<p className='filmmakerQ'>If you have a link to a portfolio please share below:</p>
<input ref={register({required: false})} onChange={e => setportfolio(e.target.value)} className='inputsThree' name='portfolio' autoComplete='off'></input>
<p className='minifieldsNew'>This is your chance to show your work. This will be shared on your profile</p>
<p className='filmmakerQ'>Anything else you want to share about yourself?</p>
<input ref={register({required: false})} onChange={e => setaboutYou(e.target.value)} className='inputsThree' name='aboutYou' autoComplete='off'></input>
<p className='minifieldsNewNew'>Our community is very interested in learning more about you as a filmmaker</p>
</div>
<div>
<button type='submit' className='signupButton3'>Sign Up</button>
{/* <a onClick={handleSubmit(onSubmit)} type='submit' className='doneButtontwo'>
<span>Done</span>
</a> */}
<div>
<a href='/GetStarted' className='later'>I'll do this later</a>
</div>
</div>
</form>
Use insomnia I see that the update endpoints work; additionally I see that if I manually take a userId and use it instead of the ":id" in the axios request, then the PUT request will update successfully.
If I send the form data right now on my local environment the network response is:
"Error: CastError: Cast to ObjectId failed for value \":id\" at path \"_id\" for model \"Users\""
I appreciate the help!

Related

Cannot access 'useState' before initialization in react.js

In react.js I am adding a form with some parameter.
import React , {useState} from "react";
AddUser component has some parameter in which I have to store data.
const AddUser = () => {
const [user, useState] = useState({
name: " ",
username: " ",
email: " ",
phone: " ",
website: " "
});
This code is used for initializing the parameter of useState.
const {name,username,email,phone,website} = user;
const onInputChange = e => {
console.log(e.target.value)
}
return (
<div className="container mt-5">
<div className="w-75 mx-auto shadow p-5">
<h2 className="text-center mb-4">Add User</h2>
This is the form where I submit some data of parameters.
<form>
<div class="form-group mb-4">
<input type="text" value={name} name="name" onChange={e => onInputChange(e)} class="form-control" aria-describedby="emailHelp" placeholder="Enter Name" />
</div>
<div class="form-group mb-4">
<input type="text" value={username} name="username" onChange={e => onInputChange(e)} class="form-control" placeholder="Enter Username" />
</div>
<div class="form-group mb-4">
<input type="email" value={email} name="email" onChange={e => onInputChange(e)} class="form-control" aria-describedby="emailHelp" placeholder="Enter email" />
</div>
<div class="form-group mb-4">
<input type="text" value={phone} name="phone" onChange={e => onInputChange(e)} class="form-control" placeholder="Enter Contact" />
</div>
<div class="form-group mb-4">
<input type="text" value={website} name="website" onChange={e => onInputChange(e)} class="form-control" placeholder="Enter Website" />
</div>
<button type="submit" class="btn btn-primary">Add User</button>
</form>
</div>
</div>
)
}
export default AddUser;
Error:
Uncaught ReferenceError: Cannot access 'useState' before initialization
at AddUser (AddUser.js:4:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20074:1)
at beginWork (react-dom.development.js:21587:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
at renderRootSync (react-dom.development.js:26434:1)
at recoverFromConcurrentError (react-dom.development.js:25850:1)
at performConcurrentWorkOnRoot (react-dom.development.js:25750:1)
useState is a react hook, you cannot use its name to name a variable or function. Change your AddUser code shown on this page to this:
const AddUser = () => {
const [user, setUser] = useState({
name: " ",
username: " ",
email: " ",
phone: " ",
website: " "
});

How to integrate 2checkout with reactjs and nodejs?

I am trying to integrate 2checkout API in my reactjs &nodejs project.I reffered the documents which 2co provided.I created an account and in that webhooks&API i have "Merchant Code" and "Secret Key" but there is no "Publishable key" and "Private Key" Why?
what i have is:
render = () => {
return(
<form id="myCCForm" onSubmit={this.Submit}>
<input
id="token"
name="token"
type="hidden"
value=""
></input>
<div>
<label>
<span>Card Number</span>
</label>
<input
id="ccNo"
type="text"
size="20"
value=""
autocomplete="off"
required
/>
</div>
<div>
<label>
<span>Expiration Date (MM/YYYY)</span>
</label>
<input
type="text"
size="2"
id="expMonth"
required
></input>
<span> / </span>
<input
type="text"
size="2"
id="expYear"
required
></input>
</div>
<div>
<label>
<span>CVC</span>
</label>
<input
id="cvv"
size="4"
type="text"
value=""
autocomplete="off"
required
></input>
</div>
<input type="submit" value="Submit Payment"></input>
</form>
)}
submit=()=>{
let args = {
sellerId: "",//gave merchant code here
publishableKey: "",//as there is no publishable key what will give here?
ccNo: "",
cvv: "",
expMonth: "",
expYear: ""
};
window.TCO.loadPubKey("sandbox", () => {
window.TCO.requestToken(args).then(data => {
console.log("data");
});
});
How can i resolve this problem?

Cannot POST Form in Node

I am trying to post a simple form from a static page to a database and then re-render the page. Right now I am getting a "Cannot Post /Index" error.
Here is my the form code:
<div class="contact-form">
<form action="/index" method="post">
<div class="col-md-6">
<input type="text" class="form-control" placeholder="Name" name="name">
</div>
<div class="col-md-6">
<input type="email" class="form-control" placeholder="Email" name="email">
</div>
<div class="col-md-6">
<input type="tel" class="form-control" placeholder="Phone Number" name="phone">
</div>
<div class="col-md-6">
<input type="text" class="form-control" placeholder="# of Trucks" name="truckNum">
</div>
<div class="col-md-12">
<input type="text" class="form-control" placeholder="Company" name="company">
</div>
<div class="col-md-12">
<input type="text" class="form-control" placeholder="Address" name="address">
</div>
<div class="col-md-12">
<textarea class="form-control" placeholder="Message" rows="4" name="message"></textarea>
</div>
<div class="col-md-8">
<input type="submit" class="form-control text-uppercase" value="Send">
</div>
</form>
</div>
Here is the router code:
app.get("/", function(req, res) {
res.sendFile(path.join(__dirname, "/../public/index.html"));
});
app.post("/", function(req,res){
db.Contact.create({
name: req.body.name,
email: req.body.email,
phone: req.body.phone,
company:req.body.company,
address:req.body.address,
truckNumber:req.body.truckNum
}).then(function(data) {
res.sendFile(path.join(__dirname, "/../public/index.html"));
});
})
};
Change '/index' to '/' in<form action="/index" method="post">.

Register new 'etudiant'

Hello so i want to register a new user called 'etudiant' in my mongodb with a post request with
<form method="post" action="register">
<h1>Create Account</h1>
<div>
<input type="text" class="form-control" placeholder="first_name" required="required" name="first_name"/>
</div>
<div>
<input type="text" class="form-control" placeholder="last_name" required="required" name="last_name"/>
</div>
<div>
<input type="text" class="form-control" placeholder="cin" required="required" name="cin"/>
</div>
<div>
<input type="text" class="form-control" placeholder="adress" required="required" name="adress"/>
</div>
<div>
<input type="text" class="form-control" placeholder="date_naissance" required="required" name="date_naissance"/>
</div>
<div>
<input type="email" class="form-control" placeholder="Email" required="required" name="mail"/>
</div>
<div>
<input type="password" class="form-control" placeholder="Password" required="required" name="pwd"/>
</div>
<div style="margin:auto;">
<center><input type="submit" value="Register"></center>
</div>
</form>
and the controller for this form is
function register (req, res) {
//create etudiant
var etudiant{
first_name:req.body.first_name,
last_name:req.body.last_name,
cin:req.body.cin,
adress:req.body.adress,
username:req.body.username,
email:req.body.email,
pwd:req.body.pwd
}
//use etudiant model to insert/save
var newetudiant = new Etudiant(etudiant);
//save etudiant
newetudiant.save();
//redirect
res.redirect('/');
}
in the console i got this error that i don't find a solution for
my error
i'm sorry i was working 9hours straight i didn't see my error xD
problem solved still if you look at the
newetudiant.save();
it's right but still doesn't save data to the db

Displaying list one by one in angular2

I am trying to display a list a question and when the user clicks submit, the next question would be displayed. For now, I am able to display all the questions on a page. I tried using a flag like other posts suggest but to no success. How would I go about this? This is the appropriate working code without the flag.
<div class="card" *ngIf="!isLoading">
<div class="card-block text-md-center" *ngFor="let question of questions">
<form>
<fieldset class="form-group">
<h1>{{question.name}}</h1>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1"
checked>
{{question.a_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
{{question.b_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3">
{{question.c_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios4" value="option4">
{{question.d_Answer}}
</label>
</div>
</fieldset>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
This is the code I tried with by hiding the questions based on indexed. It display one question but does not go to the next one when submit is clicked.
<div class="card" *ngIf="!isLoading">
<div class="card-block text-md-center" *ngFor="let question of questions; let i=index">
<form [hidden]="currentQuestionNumber !== i">
<fieldset class="form-group">
<h1>{{question.name}}</h1>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1"
checked>
{{question.a_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
{{question.b_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3">
{{question.c_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios4" value="option4">
{{question.d_Answer}}
</label>
</div>
</fieldset>
<button type="submit" class="btn btn-primary" onclick="setGoToNextTrue()">Submit</button>
</form>
</div>
</div>
</div>
Any help or pointers would be appreciated, thanks!
Component.ts file
import { Component, OnInit } from '#angular/core';
import { Http } from '#angular/http';
import { FormGroup, FormControl, Validators, FormBuilder } from '#angular/forms';
import { ToastComponent } from '../shared/toast/toast.component';
import { DataService } from '../services/data.service';
#Component({
selector: 'app-student',
templateUrl: './student.component.html',
styleUrls: ['./student.component.css']
})
export class StudentComponent implements OnInit {
questions = [];
isLoading = true;
currentQuestionNumber;
question = {};
addQuestionForm: FormGroup;
name = new FormControl('', Validators.required);
a_Answer = new FormControl('', Validators.required);
b_Answer = new FormControl('', Validators.required);
c_Answer = new FormControl('', Validators.required);
d_Answer = new FormControl('', Validators.required);
constructor(private http: Http,
private dataService: DataService,
public toast: ToastComponent,
private formBuilder: FormBuilder)
{
this.currentQuestionNumber = 0;
}
ngOnInit() {
this.getQuestions();
//this.currentQuestionNumber = 0;
this.addQuestionForm = this.formBuilder.group({
name: this.name,
a_Answer: this.a_Answer,
b_Answer: this.b_Answer,
c_Answer: this.c_Answer,
d_Answer: this.d_Answer
});
}
getQuestions() {
this.dataService.getQuestions().subscribe(
data => this.questions = data,
error => console.log(error),
() => this.isLoading = false
);
}
setGoToNextTrue()
{
this.currentQuestionNumber++;
}
}
Attempt#2
component.html
<div class="card" *ngIf="isLoading">
<h4 class="card-header">Loading...</h4>
<div class="card-block text-xs-center">
<i class="fa fa-circle-o-notch fa-spin fa-3x"></i>
</div>
</div>
<div class="card" *ngIf="!isLoading">
<div class="card-block text-md-center">
<form (ngSubmit)="onSubmit()">
<fieldset class="form-group hide" *ngFor="let question of questions;let i=index" [class.show]="i == questionIndex">
<h1>{{question.name}}</h1>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1"
checked>
{{question.a_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
{{question.b_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3">
{{question.c_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios4" value="option4">
{{question.d_Answer}}
</label>
</div>
</fieldset>
<p *ngIf="questionIndex == (questions.length - 1)">This is the last one.</p>
<button type="submit" class="btn btn-primary" onclick="setGoToNextTrue">Submit</button>
</form>
</div>
</div>
component.ts
import { Component, OnInit } from '#angular/core';
import { Http } from '#angular/http';
import { FormGroup, FormControl, Validators, FormBuilder } from '#angular/forms';
import { ToastComponent } from '../shared/toast/toast.component';
import { DataService } from '../services/data.service';
#Component({
selector: 'app-student',
templateUrl: './student.component.html',
styleUrls: ['./student.component.css']
})
export class StudentComponent implements OnInit {
questions = [];
isLoading = true;
//currentQuestionNumber;
questionIndex = 0;
question = {};
addQuestionForm: FormGroup;
name = new FormControl('', Validators.required);
a_Answer = new FormControl('', Validators.required);
b_Answer = new FormControl('', Validators.required);
c_Answer = new FormControl('', Validators.required);
d_Answer = new FormControl('', Validators.required);
constructor(private http: Http,
private dataService: DataService,
public toast: ToastComponent,
private formBuilder: FormBuilder)
{
}
ngOnInit() {
this.getQuestions();
//this.currentQuestionNumber = 0;
for(let i = 1; i < 4; i++) {
this.addQuestionForm = this.formBuilder.group({
name: this.name,
a_Answer: this.a_Answer,
b_Answer: this.b_Answer,
c_Answer: this.c_Answer,
d_Answer: this.d_Answer
});
}
this.isLoading = false;
}
getQuestions() {
this.dataService.getQuestions().subscribe(
data => this.questions = data,
error => console.log(error),
() => this.isLoading = false
);
}
private onSubmit() {
if(this.questionIndex < (this.questions.length - 1)) {
this.questionIndex++;
}
}
}
You can push one question to the array when submit button clicked or use the index to hide some questions.
There is a demo https://embed.plnkr.co/lc6GBFzcjS2Ly0z5QXZT/
You can use the [hidden] directive in your template for each form.
When generating the template each form will be associated to the index of the question in your questions array.
You will need to declare a property in you code behind which will declare the current displayed question.
constructor (){
this.currentQuestionNumber = 0;
}
setGoToNextTrue(){
this.currentQuestionNumber++;
//Other stuff.. for exmaple checking that you've reach the last question
}
In the constructor, By default you can decide to display the first question in the array.
Then your template would look like :
<div class="card" *ngIf="!isLoading">
<div class="card-block text-md-center" *ngFor="let question of questions;let i=index">
<div *ngIf ="nextQuestion">
<form [hidden]="currentQuestionNumber !== i">
<fieldset class="form-group">
<h1>{{question.name}}</h1>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1"
checked>
{{question.a_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
{{question.b_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3">
{{question.c_Answer}}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios4" value="option4">
{{question.d_Answer}}
</label>
</div>
{{setGoToNextFalse()}}
</fieldset>
<button type="submit" class="btn btn-primary" onclick="setGoToNextTrue()">Submit</button>
</form>
</div>
</div>
</div>

Resources