How to prefill data in vue form? - forms

I am using vue form to edit one item, but I cannot conclude in which method should I assign a values to categoryName and description to make those values ​​appear in form?
I tried to make axios call and assign response to categoryName and description in the methods: created, mounted, beforeMouned, but it does not show values of categoryName and description in input fields, although values are obtained from the backend. Also v-model.lazy does not give results.
This is my code:
<template>
<div class="pt-5">
<form #submit.prevent="submitCategory">
<div class="form-group">
<label for="categoryName">Category name</label>
<input v-model.lazy="categoryName" value="categoryName" type="text" class="form-control" id="categoryName" aria-describedby="categoryNameHelp" placeholder="Enter category name">
</div>
<br>
<div class="form-group">
<label for="description">Description</label>
<input v-model="description" type="text" class="form-control" id="description" placeholder="Enter description">
</div>
<br>
<button type="submit" class="btn btn-primary mt-2">Submit</button>
</form>
</div>
</template>
<script>
export default {
name: "EditCategory",
data() {
return {
categoryName: '',
description: '',
}
},
beforeMount () {
this.$axios.get(`/api/categories/${this.$route.params.id}`,{
id: this.$route.params.id
}).then((response) => {
console.log(response.data)
this.categoryName = response.categoryName;
this.description = response.description;
}); },
methods: {
submitCategory() {
this.$axios.post('/api/categories', {
categoryName: this.categoryName,
description: this.description,
}).then(response => {
console.log(response)
this.$router.push({name: 'Categories'});
})
},
initialize () {
},
},
}
</script>
<style scoped>
</style>

Axios Response object
When we send a request to a server, it returns a response. The Axios response object consists of:
data - the payload returned from the server
status - the HTTP code returned from the server
headers - headers sent by server
You did console.log(response.data) in BeforeMount Hook. You will get your required data under response.data object
this.categoryName = response.data.categoryName;
this.description = response.data.description;

Related

Need help getting Nuxt 3 form to post emails to my Strapi 4 Subscriber collection

I have the following code but it does not post to my Subscriber collection. When I put in an email address it does not post to my subscriber collection type. Also it does not console.log
Using Nuxt3/Strapi4
<template>
<div class="relative flex justify-center w-full h-64 pb-16 mt-14 subscribe-bg">
<Container>
<div class="w-full mx-auto lg:w-3/6">
<div class="px-10 -mt-12 text-center bg-white rounded-lg shadow-xl py-9 subscribe-box">
<Heading tag="h3" font-style="h3">Subscribe</Heading>
<Heading tag="h2" font-style="h2">Never miss a planner</Heading>
<p
class="w-full px-2 mx-auto text-center pb-7 text-brand-grey-400"
>Subscribe to receice the worlds most cutting edge planner news direct to your inbox. Our newsletter is on fire.</p>
<div class="flex items-center">
<form #submit.prevent="handleSuscribe">
<input-field
id="email"
v-model="email.email"
type="email"
name="email"
placeholder="Your email"
class="w-3/4 mr-8"
/>
<Btn class="h-full" type="submit">Subscribe</Btn>
</form>
</div>
</div>
</div>
</Container>
</div>
</template>
<script setup>
import { useToast } from 'vue-toastification';
const toast = useToast();
const email = ref({ email: "" })
const handleSuscribe = async () => {
await $fetch("http://localhost:1337/api/subscribers", {
method: "POST",
body: {
data: {
email: email.value,
}
}
})
console.log(email.value)
console.log(handleSuscribe)
}
</script>
Tried to convert from the following code from Nuxt 2. It looked pretty simple at first but now I am running into issues.
<template>
<div
class="sm:flex mx-auto items-center m-10 justify-center space-x-6 sm:space-x-20 m-3 sm:m-6 mx-6"
>
<div>
<h1 class="text-lg m-7">Sign Up For NewsLetter</h1>
</div>
<div>
<form #submit="handleSuscribe">
<input
id=""
v-model="email"
class="p-2 m-3 sm:m-0 border border-solid border-t-0 border-l-0 border-r-0 border-b-1 outline-none border-black"
type="email"
name=""
placeholder="email"
/>
<button type="submit" class="button--grey">Subscribe</button>
</form>
</div>
</div>
</template>
<script>
export default {
name: 'NewsLetter',
data() {
return {
email: '',
}
},
methods: {
async handleSuscribe(e) {
e.preventDefault()
this.$swal({
title: 'Successful!',
text: 'Thanks for Subscribing',
icon: 'success',
button: 'Ok',
})
await this.$strapi.$subscribers.create({ Email: this.email })
this.email = '' // clear email input
},
},
}
</script>

Why am I getting "500 (Internal Server Error)" and "Uncaught (in promise) SyntaxError: Unexpected token < "?

I am trying to insert some data into the database through a fetch API POST request to a Next.js API route but I am getting the following two error messages in the browser's console:
api/addCompany/addCompany:1 Failed to load resource: the server responded with a status of 500 (Internal Server Error) register:1
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
These are my project's folders (it's relevant because of Next.js's routing system)
This is the component where I am doing the fetch API request (please don't judge my poor Typescript skills, I am new to it, still not finding the propper event type):
import styles from '../styles/Register.module.css'
import { NextPage } from "next"
import { prisma } from '../prisma/prisma_client';
import { Prisma } from '#prisma/client';
import { useSession } from "next-auth/react"
const Register: NextPage = () => {
const createCompany: any = async (event: any) => {
event.preventDefault()
const company: Prisma.CompanyCreateInput = {
companyName: event.target.companyName.value,
gender: event.target.gender.value,
firstName: event.target.firstName.value,
lastName: event.target.lastName.value,
street: event.target.street.value,
houseNumber: parseInt(event.target.houseNumber.value),
postcode: parseInt(event.target.postcode.value),
city: event.target.city.value,
country: event.target.country.value,
countryCode: event.target.countryCode.value,
callNumber: parseInt(event.target.callNumber.value),
emailAddress: event.target.emailAddress.value,
website: event.target.website.value,
socials: {},
companyUser: {
connect: { id: 'cl0y4y8xo0021mwtcmwlqfif6' }
}
}
const companyJSON = JSON.stringify(company)
const endpoint = '/api/addCompany/addCompany'
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: companyJSON,
}
const response = await fetch(endpoint, options)
const data = await response.json()
console.log(data)
}
return (
<form onSubmit={createCompany} className={styles.form} id="signupForm" noValidate>
<h2>Company Information</h2>
<div className="fieldWrapper">
<input type="text" id="companyName" name="companyName" placeholder=" " />
<label htmlFor="companyName">Company Name<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" list="genders" id="gender" name="gender" placeholder=" " />
<label htmlFor="gender">Gender<span>*</span></label>
<div className='errorMessage'></div>
<datalist id="genders">
<option>Female</option>
<option>Male</option>
</datalist>
</div>
<div className="fieldWrapper">
<input type="text" id="firstName" name="firstName" placeholder=" " />
<label htmlFor="firstName">First Name<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" id="lastName" name="lastName" placeholder=" " />
<label htmlFor="lastName">Last Name<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" id="street" name="street" placeholder=" " />
<label htmlFor="street">Street<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="number" id="houseNumber" name="houseNumber" placeholder=" " />
<label htmlFor="houseNumber">House Number<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="number" id="postcode" name="postcode" placeholder=" " />
<label htmlFor="postcode">Postcode<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" id="city" name="city" placeholder=" " />
<label htmlFor="city">City<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" id="country" name="country" placeholder=" " />
<label htmlFor="country">Country<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" id="countryCode" name="countryCode" placeholder=" " />
<label htmlFor="countryCode">Country Code<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="number" id="callNumber" name="callNumber" placeholder=" " />
<label htmlFor="callNumber">Call Number<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="email" id="emailAddress" name="emailAddress" placeholder=" " />
<label htmlFor="emailAddress">Email Address<span>*</span></label>
<div className='errorMessage'></div>
</div>
<div className="fieldWrapper">
<input type="text" id="website" name="website" placeholder=" " />
<label htmlFor="website">Website</label>
</div>
<div className="fieldWrapper">
<input type="text" id="socials" name="socials" placeholder=" " />
<label htmlFor="socials">Socials</label>
</div>
<div className="fieldWrapper">
<button type="submit">Save</button>
</div>
</form>
)
}
export default Register
And this is the the addCompany file's code which serves as the Next.js API route for my fetch API request:
import { Prisma } from '#prisma/client';
import { NextApiRequest, NextApiResponse } from 'next';
import { prisma } from '../../../prisma/prisma_client';
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const {body} = req;
const companyData: Prisma.CompanyCreateInput = JSON.parse(body);
const addCompany = await prisma.company.create({
data: companyData
})
res.status(200).json(addCompany);
}
export default handler
I appreciate any help. Thank you.
I tried to comment out
const data = await response.json() console.log(data)
in the Register component so the error "Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0" disappeared but that is no solution to the problem at all.
I also tried to adjust the route of my fetch request to any possible option because I wasn't sure how exactly Next.js autocompletes it, for example I tried: '/api/addCompany/addCompany.ts' and so on.
I expect the problem to be something small, I hope it isn't typo.
Thank you again.
PS: I also checked similar posts on this matter but couldn't find a fix for my problem.
There is no need to reparse the body data in the API endpoint because Next.js middleware convert that data to an object already:
API routes provide built in middlewares which parse the incoming
request (req). Those middlewares are:
req.cookies - An object containing the cookies sent by the request. Defaults to {}
req.query - An object containing the query string. Defaults to {}
req.body - An object containing the body parsed by content-type, or null if no body was sent
something like below should work:
import { Prisma } from '#prisma/client';
import { NextApiRequest, NextApiResponse } from 'next';
import { prisma } from '../../../prisma/prisma_client';
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const {body: companyData} = req;
//const companyData: Prisma.CompanyCreateInput = JSON.parse(body);<- No need to reparse the data here
const addCompany = await prisma.company.create({
data: companyData
})
res.status(200).json(addCompany);
}
export default handler
Thanks to this answer here for clarification.

getting error when update button is pressed

I have a vue application which inserts, updates and delete posts by using mongodb but i am having a problem with the update function. when i press the button which updates the posts i am getting the following error. note in the postComponent.vue i just added the template to show how the form is being submitted and the function in the sciprt tag updatePost
Access to fetch at 'http://localhost:5000/api/posts/5e31a39024a21d44bc4654af' from origin 'http://localhost:8080' has been blocked by CORS policy: Method UPDATE is not allowed by Access-Control-Allow-Methods in preflight response.
posts.js
//update posts
router.put('/:id', async (req,res) => {
const posts = await loadpostscollection();
await posts.updateOne({
topic: req.body.topic,
price: req.body.price,
location: req.body.location,
provider: req.body. provider,
createdAt: new Date()
});
res.status(201).send();
});
postServise.js
//update Posts
static updatePost( id, topic, price, location, provider) {
return fetch(url + id, {
method: "UPDATE",
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({
topic,
price,
location,
provider
}
)
});
}
postComponent.vue
<template>
<div class ="container">
<router-link to="/postComponent" >Show me post component</router-link>
<h1>Create a new course</h1>
<div class="create-post">
<label for="create-topic">Add topic: </label>
<br>
<br>
<input type="text" id="create-topic" v-model="topic" placeholder="enter" required>
<br>
<br>
<label for="create-price">Add a price: </label>
<br>
<br>
<input type="text" id="create-price" v-model="price" placeholder="enter">
<br>
<br>
<label for="create-location">Add a location: </label>
<br>
<br>
<input type="text" id="create-location" v-model="location" placeholder="enter">
<br>
<br>
<label for="create-provider">Add a provider: </label>
<br>
<br>
<input type="text" id="create-provider" v-model="provider" placeholder="enter">
<br>
<br>
<button v-on:click="insertPost">Create course</button>
</div>
<hr>
<p class="error" v-if="error">{{ error }}</p>
<div class="posts-container">
<div class="post"
v-for="(post, index) in posts"
v-bind:item="post"
v-bind:index="index"
v-bind:key="post._id">
<br>
<p>Course topic:</p>
<p class="text">{{post.topic}} </p>
<p>Course price:</p>
<p class="text"> {{post.price}} </p>
<p>Course location:</p>
<p class="text">{{post.location}} </p>
<p>Created by:</p>
<p class="text"> {{post.provider}} </p>
<button v-on:click="deletePost(post._id)">Delete course</button>
<br>
<br>
<br>
<br>
<input type="text" v-model="post.topic"/>
<input type="text" v-model="post.price"/>
<br>
<br>
<input type="text" v-model="post.location"/>
<br>
<br>
<input type="text" v-model="post.provider"/>
<button v-on:click="updatePost(post)">Update course</button>
</div>
</div>
</div>
</template>
<script>
async updatePost({ _id: id, topic, price, location, provider }) {
await postService.updatePost(id, topic, price, location, provider);
this.posts = await postService.getPosts();
},
</script>
index.js
const express = require ('express');
const bodyparser = require ('body-parser');
const cors = require ('cors');
const app = express();
app.use(bodyparser.json());
app.use(cors({ origin: '*'}));
const posts = require('./api/posts');
const users = require('./api/users');
app.use('/api/posts', posts);
app.use('/api/users', users);
const port = process.env.port || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
https://i.stack.imgur.com/75fRb.png
Is not a problem of vue or JS, it's the CORS request problem. You must to allow CROS request on backend, or change request URI to http://localhost:8080/api/posts/5e31a39024a21d44bc4654af.

Can't clear form/state after input in React.js

I have a form which ultimately will be used as the UI to make some API calls to Open weather map.
Right now when I submit the a zip code in the input field, upon submission [object Object] propagates the field like in the screen shot below.
The call to the API is working as I am getting the JSON for the correct zip code...
But shouldn't this in the handleSubmit take care of everything i.e. using Object.assign to create new state and then using form.zipcode.value = ''; to clear out the input?
Thanks in advance!!
handleSubmit(event) {
event.preventDefault();
var form = document.forms.weatherApp;
api.getWeatherByZip(this.state.zipcode).then(
function(zip) {
console.log('zip', zip);
this.setState(function() {
return {
zipcode: Object.assign({}, zip),
};
});
}.bind(this)
);
form.zipcode.value = '';
}
I have enclosed all of the component's code here.
import React, { Component } from 'react';
import * as api from '../utils/api';
import '../scss/app.scss';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
zipcode: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
zipcode: event.target.value,
});
}
handleSubmit(event) {
event.preventDefault();
var form = document.forms.weatherApp;
api.getWeatherByZip(this.state.zipcode).then(
function(zip) {
console.log('zip', zip);
this.setState(function() {
return {
zipcode: Object.assign({}, zip),
};
});
}.bind(this)
);
form.zipcode.value = '';
}
render() {
return (
<div className="container">
<form name="weatherApp" onSubmit={this.handleSubmit}>
<h2>Open Weather App</h2>
<div className="row">
<div className="one-half column">
<label htmlFor="insertMode">Insert your location</label>
<input
name="zipcode"
className="u-full-width"
placeholder="please enter your zipcode"
type="text"
autoComplete="off"
value={this.state.zipcode}
onChange={this.handleChange}
/>
</div>
<div className="one-half column">
<label htmlFor="showMin">show minimum</label>
<input type="checkbox" />
<label htmlFor="showMax">show maximum</label>
<input type="checkbox" />
<label htmlFor="showMean">show mean</label>
<input type="checkbox" />
</div>
</div>
<div className="row">
<div className="two-half column">
<input type="submit" value="Submit" />
</div>
</div>
</form>
</div>
);
}
}
You should let react manage the changes to the DOM rather that editing it manually. As the value of your input field is already bound to this.state.zipcode to reset it just invoke this.setState({zipcode: ''}) instead of form.zipcode.value='';.

Set model date defaultValue to string

I try to build a 'task manager' to log the tasks that my customers send me.
I have my new-task.hbs form
<div id="new-task-form" class="col-md-12">
<form>
<div class="form-group">
<label>Customer</label>
{{input type="text" class="form-control" value=customer placeholder="Add Customer..."}}
</div>
<div class="form-group">
<label>Task</label>
{{textarea class="form-control" value=task placeholder="Add Task..."}}
</div>
<div class="form-group">
<label>Incoming</label>
{{input type="number" class="form-control" value=incoming placeholder="Bring it on..."}}
</div>
<div class="form-group">
<label>Pending</label>
{{input type="number" class="form-control" value=pending placeholder="Don't bring it on..."}}
</div>
<div class="form-group">
<label>Closed Date</label>
{{input type="date" class="form-control" value=closed_date placeholder="Please close me..."}}
</div>
<button {{action 'addTask'}} class="btn btn-primary">Submit</button>
</form>
My controller.
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
addTask: function(){
var customer = this.get('customer');
var task = this.get('task');
var incoming = this.get('incoming');
var pending = this.get('pending');
var closed_date = this.get('closed_date');
//Create new task
var newTask = this.store.createRecord('task',{
customer: customer,
task: task,
incoming: incoming,
pending: pending,
closed_date: closed_date
});
//save to db
newTask.save();
}
}
});
And the model
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend({
customer: attr('string'),
task: attr('string'),
incoming: attr('number', { defaultValue: 0 }),
pending: attr('number', { defaultValue: 0 }),
closed_date: attr('date'),
created: attr('string', {
defaultValue: function(){
return new Date();
}
})
});
How can i set a model defaultValue for a the closed_date input to a string "Not entered yet"?
If i leave it like this and not enter a value i get an "Invalid Date".
closed_date: attr('date')
If i set this i get the current date.
closed_date: attr('date', { defaultValue: 'Not entered yet' })
From my experience I suggest you leave closed_date as it is (as date) and focus on DISPLAYING Not entered yet in each place that you want to show it when closed_date isn't entered.
For example when you show model values in template you can use:
Closed date: {{if model.closed_date model.closed_date 'Not entered yet'}}
Consider using ember-pikaday for a nice date-selection experience (which also gives you the placeholder functionality you are looking for!).
Furthermore, I'd suggest that you use the model hook of your new-task route to do your model setup. Combine that with ember-data-route to do cleanup on route exit, and you should be good to go:
router.js:
this.route('tasks', function() {
this.route('new');
});
routes/tasks/new.js:
import Ember from 'ember';
import DataRoute from 'ember-data-route';
export default Route.extend(DataRoute, {
model() {
return this.store.createRecord('task');
}
});
Note below how the form field values have been updated to model.fieldName. These values are bound to the model you created in your route's model hook.
templates/tasks/new.hbs:
<div id="new-task-form" class="col-md-12">
<form>
<div class="form-group">
<label>Customer</label>
{{input type="text" class="form-control" value=model.customer placeholder="Add Customer..."}}
</div>
<div class="form-group">
<label>Task</label>
{{textarea class="form-control" value=model.task placeholder="Add Task..."}}
</div>
<div class="form-group">
<label>Incoming</label>
{{input type="number" class="form-control" value=model.incoming placeholder="Bring it on..."}}
</div>
<div class="form-group">
<label>Pending</label>
{{input type="number" class="form-control" value=model.pending placeholder="Don't bring it on..."}}
</div>
<div class="form-group">
<label>
Closed Date:
{{pikaday-input value=model.closedDate placeholder="Please close me..."}}
</label>
</div>
<button {{action 'addTask'}} class="btn btn-primary">Submit</button>
</form>
Note: prefer camelCasedMultipleWordModelAttributeName vs underscored_attribute_name
models/task.js:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend({
customer: attr('string'),
task: attr('string'),
incoming: attr('number', { defaultValue: 0 }),
pending: attr('number', { defaultValue: 0 }),
closedDate: attr('date', {
defaultValue() { return new Date(); }
}),
created: attr('string', {
defaultValue() { return new Date(); }
})
});
Now the nice part. Here's what your controller action looks like when you do your setup in your route's model hook:
controllers/tasks/new.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
addTask: function(){
this.get('model').save();
}
}
});
and for extra credit you could install ember-route-action-helper and move the controller action onto the route and remove the controller completely.