How to Using Json(Mongo DB) data in AngularJS 2 expression - mongodb

I'm develop in ng2 rc4 and my User data stored Mongo DB. User's can edit their data in my page, but my editing page hav got a problem. My source looks like this:
import { User } from './user.service.ts';
#component(
selector: 'edit-user',
template: `
Email : <input type="text" [(ngModel)]="userInfo.email"><br />
Name : <input type="text" [(ngModel)]="userInfo.name"><br />
Address : <input type="text" [(ngModel)]="userInfo.address"><br />
Tel :
<input type="text" [(ngModel)]="userInfo.tel.tel1">-
<input type="text" [(ngModel)]="userInfo.tel.tel2">-
<input type="text" [(ngModel)]="userInfo.tel.tel3"><br />
<button>Submit</button>
`,
providers: [ User ]
)
export class EditUser {
private userInfo: any = {
'email': '',
'name': '',
'address': '',
'tel': {
'tel1': '',
'tel2': '',
'tel3': ''
}
};
constructor(private user: User) {
}
ngOnInit() {
this.getUser();
}
getUser() {
this.user.getUser( ... )
.then(res => {
...
// case 1
// res = {'email': 'a#a.a', 'name': 'NameA', 'address': 'aaa', 'tel': {'tel1': '1', 'tel2': '2', 'tel3': '3'}};
// case 2
// res = {'email': 'b#b.b', 'name': 'NameB'};
this.userInfo = res;
...
})
.catch( ... )
}
}
Everything is okay when in case 1 but in case 2 there is no tel object and input tag throws error because of the missing tel object in res. The user was not entering tel information in the case 2. So it is a 2 way binding error: undefined tel property of userInfo. don't expression, don't enter the tel.tel1 property.
I can't change mongoDB and json hierarchy. How can I resolve this?

Assign empty object to tel if empty
res.tel = res.tel || {};
this.userInfo = res;

Related

How to add current user id to the axios.get request?

how can I add current user id to the axios.get request url in the front end code?
here are my codes;
backend: urls.py
urlpatterns = [
path('<int:pk>/', UserDetail.as_view()),
]
and views.py
class UserDetail(APIView):
permission_classes = [AllowAny]
http_method_names = ['get', 'head', 'post']
"""
Retrieve, update or delete a user instance.
"""
def get_object(self, pk):
try:
return NewUser.objects.get(pk=pk)
except NewUser.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
user = self.get_object(pk)
serializer = CustomUserSerializer(user)
return Response(serializer.data)
frontend:
useEffect(() => {
if (localStorage.getItem("access_token")) {
axiosInstance.get('users/**???**').then((obj) => {
{
setname(obj.username)
setemail(obj.email)
setidx(obj.uid)
}
console.log(obj);
console.log(obj.data);
setTimeout(() => {
props.resetProfileFlag();
}, 3000);
});
}
}, [props.success])
If I add user id manually (like say; axiosInstance.get('users/1').then((obj) => { ...) it gets the user details.
in your axios part you need to use params like these:
useEffect(() => {
if (localStorage.getItem("access_token")) {
axiosInstance.get('users/',
{
params: {
id: '1'
}
}).then((obj) => {
{
setname(obj.username)
setemail(obj.email)
setidx(obj.uid)
}
console.log(obj);
console.log(obj.data);
setTimeout(() => {
props.resetProfileFlag();
}, 3000);
});
}
}, [props.success])
and in the backend side you can get the data also from the request.params .
Thank you Rassaka, however, still I can't get a single user details, but I get the list of all users data at the console.
I moved to DRF Viewsets and HyperlinkedModelSerializers:
class UserSerializer(serializers.HyperlinkedModelSerializer):
posts = serializers.HyperlinkedRelatedField(
many=True,
queryset=Post.objects.all(),
view_name='blog:post-detail',
)
url = serializers.HyperlinkedIdentityField(view_name='users:user-detail')
class Meta:
model = User
fields = ('url', 'id', 'user_name', 'email', 'posts')
views.py :
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
This viewset automatically provides `list` and `detail` actions.
"""
permission_classes = [AllowAny]
queryset = User.objects.all()
serializer_class = UserSerializer
#lookup_field = 'pk'
def post(self, request):
try:
refresh_token = request.data["refresh_token"]
token = RefreshToken(refresh_token)
token.blacklist()
return Response(status=status.HTTP_205_RESET_CONTENT)
except Exception as e:
return Response(status=status.HTTP_400_BAD_REQUEST)
urls.py:
urlpatterns = [
router.register(r'users/<int:pk>', views.UserViewSet),
router.register(r'users', views.UserViewSet),
]
urlpatterns = [ re_path(r'^', include(router.urls)) ]
and finally my react frontend:
const UserProfile = props => {
const [data, setData] = useState({
users: [],
});
useEffect(() => {
if (localStorage.getItem("access_token")) {
axiosInstance.get('users/', {params: { id: '1'}}).then((res) => {
setData({
users: res.data,
})
console.log(res.data);
setTimeout(() => {
props.resetProfileFlag();
}, 3000);
})
.catch(err =>{
console.log(err)
})
}
}, [setData], [props.success])
return (
<React.Fragment>
<div className="page-content">
<Container fluid>
<Row>
<Col lg="12">
<Card>
<CardBody>
<div className="d-flex">
<div className="ms-3">
<img
src={data.users.avatar}
alt=""
className="avatar-md rounded-circle img-thumbnail"
/>
</div>
<div className="align-self-center flex-1">
<div className="text-muted">
<h5>Username: {data.users.user_name} {''}</h5>
<p className="mb-1">Email: {data.users.email} {''}</p>
<p className="mb-0">Id no: {data.users.id} {''}</p>
</div>
</div>
</div>
</CardBody>
</Card>
</Col>
</Row>
</Container>
</div>
</React.Fragment>
)
}
export default UserProfile
The issue is; after login I get the right user data in the console, however, when I go to the user profile page, firstly I get this error message "GET http://127.0.0.1:8000/api/users/?id=1 401 (Unauthorized)" in the console and of course in the backend terminal. But immediate after that the backend refreshs the token ""POST /api/token/refresh/ HTTP/1.1" 200" -> "GET /api/users/?id=1 HTTP/1.1" 200". But I get all user Arrays(data) - (not the logged-in user data) in the console, however, the user profile page cannot retrieve any user data. So I can not understand if user data cannot be retrieved to the profile page because the axiosInstanse refreshes token after login or because my frontend design is wrong. Or something is wrong with the backend?? Please, your advices? ...

How to store additional fields in mongo upon user sign up using next-auth's Email Provider

I have create a login form with two fields
a field where the user can select their university
a field where the user can enter their university email address
I use next-auth's Email Provider under the hood, so when they fill out those two fields and click on "sign up", a document will automatically be created by default in my MongoDB "users" collection that looks like this
email: 'theuseremail#something.com',
emailVerified: '2022-07-16T11:54:06.848+00:00'
and the user gets an email with a magic sign link to sign in to the website.
My problem is the following:
I want to be able to store not just the user email but also the university they selected when filling out the sign up form. But the object that gets created by default in my MongoDB only has the "email" and the "emailVerified" fields. I cannot find a way to capture other data (e.g. the user's selected university) to create the user in the database.
Is there any obvious way of doing so that I am missing? I have looked around but couldn't find any working example of this! Any help is appreciated.
This is my pages/api/[...nextAuth].js file:
import NextAuth from "next-auth"
import nodemailer from 'nodemailer'
import EmailProvider from 'next-auth/providers/email'
import { MongoDBAdapter } from "#next-auth/mongodb-adapter"
import clientPromise from "../../../utils/mongoClientPromise"
const THIRTY_DAYS = 30 * 24 * 60 * 60
const THIRTY_MINUTES = 30 * 60
export default NextAuth({
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: 'jwt',
maxAge: THIRTY_DAYS,
updateAge: THIRTY_MINUTES
},
adapter: MongoDBAdapter(clientPromise),
providers: [
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM,
async sendVerificationRequest ({
identifier: email,
url,
provider: { server, from }
}) {
const { host } = new URL(url)
const transport = nodemailer.createTransport(server)
await transport.sendMail({
to: email,
from,
subject: `Sign in to ${host}`,
text: text({ url, host }),
html: html({ url, host, email })
})
}
})
],
pages: {
signIn: '/login',
}
})
function html ({ url, host, email }) {
const escapedEmail = `${email.replace(/\./g, '​.')}`
const escapedHost = `${host.replace(/\./g, '​.')}`
// Your email template here
return `
<body>
<h1>Your magic link! 🪄</h1>
<h3>Your email is ${escapedEmail}</h3>
<p>
Sign in to ${escapedHost}
</body>
`
}
// Fallback for non-HTML email clients
function text ({ url, host }) {
return `Sign in to ${host}\n${url}\n\n`
}
This is my Login page in pages/login.tsx:
import { Row, Col, Button, Input, Form, Space } from "antd";
import { useSession, signIn } from "next-auth/react";
import { getCsrfToken } from "next-auth/react"
import { useRouter } from 'next/router';
import { useState } from "react";
import UniversitySearchAndSelectDropdown from "../components/UniversitySearchAndSelectDropdown";
import data from '../mock_api_payload.json'
export default function LoginPage({ csrfToken }) {
const navigate = useRouter();
const { data: session } = useSession()
const [selectedUniversityId, setSelectedUniversityId] = useState('');
const [form] = Form.useForm();
if (session) {
navigate.push("/")
}
if (!session) {
return (
<>
<Row justify="center" style={{marginTop: '2rem'}}>
<Col>
<form method="post" action="/api/auth/signin/email">
<input name="csrfToken" type="hidden" defaultValue={csrfToken} />
<Row justify="center">
<Col>
<Space direction="vertical">
<Input
placeholder="Enter your university email address"
type="email"
id="email"
name="email"
/>
</Space>
</Col>
</Row>
<Row justify="center" style={{marginTop: '1rem'}}>
<Col>
<Button
htmlType="submit"
shape="round"
type="primary"
>Sign in</Button>
</Col>
</Row>
</form>
</Col>
</Row>
</>
)
}
};
export async function getServerSideProps(context: any) {
const csrfToken = await getCsrfToken(context)
return {
props: { csrfToken },
}
}
Thank you!

Vue.js: How to fill a form prepopulated with data from a get request?

I want to load data with a GET request and fill the data to the input data attributes at vue.js 3 like
<input id="name" type="text" v-bind:placeholder="$t('message.NamePlaceholder')" value="{{ name }}" required>
and this is my script part
<script>
export default {
data () {
return {
userInformation: {},
name: "",
}
},
mounted () {
this.getUserInformation();
},
methods () {
getUserInformation() {
this.$axios({
method: 'get',
url: 'http://127.0.0.1:8000/api/get_user_information',
}).then(response => {this.userInformation = response.data});
this.name = this.userInformation.Name;
}
},
}
But the input field contains only {{ name }}. I tried also v-bind:value, but this didn't solve the problem.
Whenever you need to bind values to attributes {{}} are unnecessary. You can just write v-bind:value="name" or :value="name"
E.g.:
<input id="name" type="text" :placeholder="message.NamePlaceholder" :value="name" required></input>
The mistake was that I have to set the variable this.name at the axios command:
this.$axios({
method: 'get',
url: 'http://127.0.0.1:8000/api/get_user_information',
}).then(response => {
this.userInformation = response.data;
this.name = this.userInformation.Name;
});

Getting asynchronous values from ant-design vue form using onValuesChange

I have a form that submits and send data to the backend using ant-design-vue. However, what I would like to achieve is give the user some form of feedback so while they type in the field they get to see the value {fullname placeholder} updated immediately, and clicking on the submit button sends it to the backend altogether.
{{ fullname || 'Your Name' }}
<a-col :xs="{ span: 24 }" :lg="{ span: 12 }">
<a-form-item label="Full Name">
<a-input
type="text"
placeholder="Your Name"
:disabled="toggleEdit === 'edit'"
v-decorator="[
'fullname',
{
initialValue: this.fullname || '',
rules: [{ required: true, message: 'Name is required!' }],
},
]"
autocomplete="name"
/> </a-form-item
></a-col>
So the {{ fullname }} at the top updates immediately the user types Similar to v-model. But I would like to know how I can achieve this in ant-design-vue form with the onValuesChange method.
You need to use v-model to bind your value on inputfirstly.
meanwhile, use #click on button with submit method
<a-input
type="text"
v-model="inputValue" <---here
placeholder="Your Name"
:disabled="toggleEdit === 'edit'"
v-decorator="['fullname',
{
initialValue: this.fullname || '',
rules: [{ required: true, message: 'Name is required!' }],
},
]"
autocomplete="name"/>
<button #click="submit"></button>
...
data(){
return{
inputValue: ""
}
}
methods:{
submit(){
// I send keyword with a object which include this inputValue by POST method
// you can change it to yours, and keyword as well
fetch("api-url").post({ keyword: this.inputValue })
.then(response.json())
.then(res => { //dosomthing when you get res from back-end })
}
}
Does above code is your requirement?

Sails.js : How to insert values in mysql database

I'm using Linux and, I'm trying to insert my Textbox values into mysql via sails.js. When I surfing the net, I didn't get any clear answer.
I have attached My Controller for create function
module.exports = {
create :function(req,res){
if(req.method=="POST"&&req.param("User",null)!=null)
{
var insert = "INSERT INTO User VALUES("+req.params.userId+",'"+req.params.loginName+"','"+req.params.userName+"','"+req.params.password+"','"+req.params.userMail+"')";
User.query(insert,function(err,record){
if(err)
{
console.log("Error");
}
else
{
console.log(record);
res.redirect('User/index');
}
});
}
},
this is my create.ejs
<form action="/user/create" method="POST">
<table>
<tr><td>UserId:<td><input type="text" name="User[userId]"><br/>
<tr><td>LoginName:<td><input type="text" name="User[loginName]"><br/>
<tr><td>UserName:<td><input type="text" name="User[userName]"><br/>
<tr><td>Password:<td><input type="text" name="User[password]"><br/>
<tr><td>UserMail:<td><input type="text" name="User[userMail]"><br/>
<tr><td><td><input type="submit" value="Register">
</form>
connection.js is:
module.exports.connections = {
mysql: {
module : 'sails-mysql',
host : 'localhost',
port : 3306,
user : 'root',
password : 'assyst',
database : 'User'
},
};
How to do basic crud operations in sails.js with mysql.
Expect if you create User API by sails generate api user it will automatically UserController.js at api/controllers and User.js at api/models.
Modify User.js at your api/models/User.js to
module.exports = {
attributes : {
userId : {type: 'string'},
loginName : {type: 'string'},
userName : {type: 'string'},
password : {type: 'string'},
userMail : {type: 'string'}
}
};
By default, it expose Blueprint API and you can POST something to user model by:
<form action="/user" method="POST">
<table>
<tr><td>UserId:<td><input type="text" name="userId"><br/>
<tr><td>LoginName:<td><input type="text" name="loginName"><br/>
<tr><td>UserName:<td><input type="text" name="userName"><br/>
<tr><td>Password:<td><input type="text" name="password"><br/>
<tr><td>UserMail:<td><input type="text" name="userMail"><br/>
<tr><td><td><input type="submit" value="Register">
</form>
That's the basic CRUD at Sails.
Here is my insert operation in sails.js with Mysql
Insert:function(req,res)
{
if(req.method=="POST")
{
console.log("Post");
var userId = req.param("userId");
var userName = req.param("userName");
var loginName =req.param("loginName");
var password =req.param("password");
var userMail =req.param("userMail");
console.log(userName);
var insert = "INSERT INTO User(UserId,LoginName,UserName,password,UserMail) VALUES("+userId+",'"+loginName+"','"+userName+"','"+password+"','"+userMail+"')";
User.query(insert,function(err,record)
{
if(err)
{
console.log(err);
}
else
{
console.log(record);
res.redirect('User/index');
}
});
}
else
{
res.render("create");
}
},