So, I Have:
UserProfile:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', unique=False)
orders = models.ManyToManyField(Order, blank=True)
Order:
class Order(models.Model):
car_brand = models.CharField(max_length=30)
car_model = models.CharField(max_length=30)
repair_type = models.CharField(max_length=30)
Register.js:
...
// Handling the form submission
const handleSubmit = (e) => {
e.preventDefault();
if (name === '' || email === '' || password === '') {
setError(true);
} else {
console.log('component Register registering ')
let user = {
username: name,
email: email,
password: password,
is_active: false,
}
axios.post('http://localhost:8000/api/users/', {
username: name,
email: email,
password: password,
is_active: false,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error.response);
});
axios.post('http://localhost:8000/api/profiles/', {
user: null,
orders: []
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error.response);
});
setSubmitted(true);
setError(false);
}
};
...
Question is:
User creation works fine, its create the user, it shows at the rest-api, and .db
How to create UserProfile? How I can add user, which I created first, and the add empty orders list??
I think you need to set the OrderSerializer in the UserProfileSerializer.
class UserProfileSerializer(serializers.ModelSerializer):
orders = OrderSerializer(many = True)
user_id = serializers.IntegerField(write_only = True)
user = UserSerializer(read_only = True)
class Meta:
model = UserProfile
fields = ['user', 'orders', 'user_id']
def create(self, validated_data):
order_ids = []
order_data = validated_data.pop('orders')
for order_item in order_data:
new_order = Order.objects.create(**order_item)
order_ids.append(new_order.id)
new_profile = UserProfile.objects.create(user_id = validated_data['user_id'])
new_profile.set(order_ids)
return new_profile
Then in post API, you need to upload user_id and orders like the following. Here I assume user has already been created and orders need to be created.
{
"user_id": 1,
"orders": [
{
"car_brand": "...",
"car_model": "...",
"repair_type": "..."
},
...
]
}
Of course, you can create user when create user profile, but in order to do that, you can change a code little bit.
Related
i am trying to store user data in mongodb using put method .my intension is to update those data if there exist or create new. but my method create new data insteade of updating..
this code is from client side(here first i uploaded my image to the imgbb then i save it to server).. .
const image = data.image[0];
const formData = new FormData();
formData.append('image',image)
const API_KEY = '4957c3c668ded462db1fb1002c4535e6';
const url = `https://api.imgbb.com/1/upload?key=${API_KEY}`;
fetch(url,{
method : 'POST',
body : formData,
})
.then(res => res.json())
.then(result => {
if(result.success){
console.log('image',result.data.url)
const img = result.data.url;
const dataOfuser = {
user : user?.displayName,
email : user?.email,
phone: data.phone,
city: data.city,
education: data.education,
img: img
}
console.log(dataOfuser)
fetch(`http://localhost:5000/user/:${user.email}`,{
method:"PUT",
headers:{
'Content-Type': 'application/json'
},
body : JSON.stringify(dataOfuser)
})
.then(res => res.json())
.then(data => {
if(data.acknowledged){
toast.success('Profile Updated')
}
})
}
})
};
these are the code from mongodb
app.put('/user/:email',async(req,res)=>{
const email = req.params.email;
const user = req.body;
const filter = { email: email };
const options = { upsert: true };
const updateDoc = {
$set: user,
};
const result = await userCollection . updateOne ( filter , updateDoc , options);
res.send(result);
});
You could try to send email and user as body and
app.put("/user/email", async (req, res) => {
const { dataOfuser } = req.body; //this finds all
const { email, user, phone, city, etc} = dataOfuser; //this extracts the values, but probably better to send each values by themselves
You can also just send user and email etc on their own, instead of as one object:
body: JSON.stringify({ user, email, phone, city, education, img })
You can also try to add curlybraces around dataOfuser in the body: JSON.stringify({ dataOfuser })
const res = await userCollection
.updateOne(
{ email: email} *find the user by his email*
{ $set: {email: email, phone: phone, city: city etc.}}) *set email to email from body*
})
You should also have default value in inputs as their current value, so the fields doesn't get overwritten as null or blank
I had this problem roles can't added when I'm using angular form whereas JSON test postman register added correctly here in frontend roles always null if someone have an idea how can I solve this issue I'll be glad.
Thank you in advance
User.Controller
#PostMapping("/signup")
public ResponseEntity<?> registerUser(#Valid #RequestBody RegistrationForm signUpRequest) {
if (utilisateurRepository.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Username is already taken!"));
}
if (utilisateurRepository.existsByEmail(signUpRequest.getEmail())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Email is already in use!"));
}
Set<String> strRoles = signUpRequest.getRoles();
Set<Role> roles = new HashSet<>();
if (strRoles == null) {
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(userRole);
} else {
strRoles.forEach(role -> {
switch (role) {
case "admin":
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(adminRole);
break;
default:
Role aideRole = roleRepository.findByName(ERole.ROLE_AIDESOIGNANTE )
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(aideRole);
}
});
}
// Create new user's account
Utilisateur user = new Utilisateur(signUpRequest.getUsername(),
signUpRequest.getEmail(),
passwordEncoder.encode(signUpRequest.getPassword()), signUpRequest.getTelephone(), roles);
user.setRoles(roles);
utilisateurRepository.save(user);
return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
}
Authentication.Service Angular
register(user): Observable<any> {
return this.http.post(AUTH_API + 'signup', {
username: user.username,
email: user.email,
telephone: user.telephone,
role: user.role,
password: user.password
}, httpOptions);
Register.Html
<div class="form-group">
<label for="role">Role</label>
<input
type="text"
class="form-control"
name="role"
[(ngModel)]="form.role"
required
#role="ngModel"
/>
</div>
Register.ts
onSubmit() {
this.authService.register(this.form).subscribe(
data => {
console.log(data);
this.isSuccessful = true;
this.isSignUpFailed = false;
},
err => {
this.errorMessage = err.error.message;
this.isSignUpFailed = true;
}
);
}
The problem is that angular forms is setting a single role and your backend is expecting roles (in plural). You can solve it by doing the following:
onSubmit() {
// use rest operator to get a rest object without role
const {role, ...rest} = this.form;
// build userData, containing the role collected above
// SignUpData is declared on Authentication.service
const userData: SignUpData = {...rest, roles: [role]};
// use the userData in your request
this.authService.register(userData).subscribe(
data => {
console.log(data);
this.isSuccessful = true;
this.isSignUpFailed = false;
},
err => {
this.errorMessage = err.error.message;
this.isSignUpFailed = true;
}
);
}
Authentication.Service Angular
export interface SignUpData {
username: string;
email: string;
telephone: string;
roles: string[];
password: string;
}
#Injectable({providedIn: 'root'})
export class AuthenticationService {
...
register(user: SignUpData): Observable<any> {
return this.http.post(AUTH_API + 'signup', user, httpOptions);
}
...
}
I'm trying to create a record on two tables when a user registers.
user.js
const db = require('../database');
const User = db.Model.extend({
tableName: 'login_user',
hasSecurePassword: true,
hasTimestamps: true,
team : () =>{
return this.hasMany('Team', 'owner_id');
}
});
module.exports = User;
team.js
const db = require('../database');
const Team = db.Model.extend({
tableName: 'team_master',
hasTimestamps: true,
user: () => {
return this.belongsTo('User', 'owner_id');
},
});
module.exports = Team;
knex migration file
exports.up = function (knex, Promise) {
return knex.schema.createTable('login_user', t => {
t.increments('id').unsigned().primary();
t.string('email').notNull();
t.string('password_digest').notNull();
t.string('fName').notNull();
t.string('lName').notNull();
t.timestamp('created_at').defaultTo(knex.fn.now())
t.timestamp('updated_at').defaultTo(knex.fn.now())
})
.createTable('team_master', t => {
t.increments('id').unsigned().primary();
t.integer('owner_id').references('id').inTable('login_user');
t.string('teamName').notNull();
t.timestamp('created_at').defaultTo(knex.fn.now())
t.timestamp('updated_at').defaultTo(knex.fn.now())
});
};
exports.down = function (knex, Promise) {
return knex.schema.dropTable('login_user').dropTable('team_master');
};
My insert code looks like the following
const user = new User({
email: req.body.email,
password: req.body.password,
fName: req.body.fName,
lName: req.body.fName,
//teamName: req.body.teamName,
});
user.save().then(() => {
res.send('User Created');
});
So in this case what I want to do is insert teamName into the team_master table with the newly created unique user ID inserted into the owner_id in team_master table.
Can someone point me in the right direction around this? Thank you.
You should be able to use the generated ID from the saved User to populate the Team, like this:
user.save()
.then(user => {
// user.id should be populated with the generated ID
return new Team({
owner_id: user.id,
// set your other team properties
}).save()
})
.then(team => {
// do something with team
})
I'm working on my first node.js application and I need some help.
I use MongoDb as database.
In my application I have created a (sign up) method that reads user input such as email & password and sets the other fields like first-name & last-name to empty strings.
exports.postSignup = (request, response, next) => {
const email = request.body.email;
const password = request.body.password;
const fonfirmPassword = request.body.confirmPassword;
User.findOne({ email: email })
.then(userDoc => {
if (userDoc) {
request.flash('error', 'Email already exists, please pick another!')
return response.redirect('/auth/signup');
}
return bcrypt.hash(password, 12)
.then(hashedPassword => {
const user = new User({
firstName: '',
lastName: '',
email: email,
photoUrl: '',
password: hashedPassword,
cart: { items: [] }
})
return user.save();
})
.then(result => {
response.redirect('/auth/login');
const signup = {
to: email,
from: 'support#company.com',
templateId: keys.SIGNUP_TEMPLATE_ID,
dynamic_template_data: {
subject: 'Signup succeeded successfully!',
},
};
sgMail.send(signup);
})
.catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
};
The code above works fine...
After a User has logged in to their account, that user is able to navigate to their profile page and set their first-name and last-name just as shown in the attached image.
enter image description here
So I have created another method that allows a User to set their first-name, last-name and photo-Url
exports.postAddProfile = (request, response, next) => {
const firstName = request.body.firstName;
const lastName = request.body.lastName;
const photoUrl = request.body.photoUrl;
User.findOne({ userId: request.user.userId })
.then(user => {
user.firstName = firstName;
user.lastName = lastName;
user.photoUrl = photoUrl;
return user.save();
})
.then(result => {
console.log('Added Profile Info');
response.redirect('/');
})
.catch(err => {
console.log(err)
});
};
This code also works fine But the issue is if a User sets their first-name, last-name and photo-Url the first time like (Jonas, Jsk and https://photourl.com)
Then the second time if a User only changes the first-name then last-name and photo-Url are again set to empty strings.
How can I avoid that?
Empty strings are falsies in JS, so just check if the response has a value that's not a empty string:
User.findOne({ userId: request.user.userId })
.then(user => {
user.firstName = firstName ? firstName : user.firstName;
user.lastName = lastName ? lastName : user.lastName;
user.photoUrl = photoUrl ? photoUrl : user.photoUrl;
return user.save();
})
I do not know why I unable to retrieve user id when creating a new account and add a role for this user.
methods.js :methods for update and insert new account driver with which I would assign the roles 'driver' for every new account ,registering a new account is going successfully, but the addition of a role does not work
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { CONST } from '../../common/constants.js';
import { Roles } from 'meteor/alanning:roles';
Meteor.methods({
updateUserProfile: (newProfile) => {
const userId = Meteor.userId();
// var isEmailChanged = currentProfile ?
// newProfile.email != currentProfile.email :
Meteor.users.update(userId, {
$set: {
profile: newProfile,
},
}, {
validationContext: 'updateUserProfile',
});
},
createDriver: (newUser) => {
var id =Accounts.createUser({
username: newUser.username,
email: newUser.email,
password: newUser.password,
profile: newUser.profile,
roles: CONST.USER_ROLES.DRIVER,
});
//console.log(Meteor.userId());
Roles.addUsersToRoles(id, roles);
},
});
Driver-join.js
Meteor.call('createDriver', data, (error) => {
if (error) {
Session.set(SESSION.ERROR, error);
} else {
FlowRouter.go('/s/driver/vehicles'); // TODO : replace with redirection by root name
}
});
roles
roles: {
type: [String],
optional: true,
allowedValues: [CONST.USER_ROLES.CLIENT, CONST.USER_ROLES.DRIVER, CONST.USER_ROLES.ADMIN],
defaultValue: CONST.USER_ROLES.CLIENT,
},
What if add this to the server?
Meteor.users.after.insert(function (userId, doc) {
Roles.addUsersToRoles(doc._id, [CONST.USER_ROLES.DRIVER])
});
Also remove roles property when you add new user, it doesn't work.
But your code should work as well. What is the roles in Roles.addUsersToRoles(id, roles);?