I am creating an application in which a user can create how to update a project, the application is being done with Vue 3 and Go, but I find a problem and that is that when I want to obtain the project data and then update the information it is generated An error, and it is that when obtaining the data from the api it does well because it shows me the information I want, the problem is when I refresh the page because the data is lost immediately.
this is an example of what the api returns me:
{
"id_project": 3,
"name": "gbhnju",
"description": "derftgyh",
"start_date": "2021-08-06T00:00:00Z",
"end_date": "2021-08-17T00:00:00Z",
"created_at": "2021-08-06T15:57:19.27Z",
"updated_at": "0001-01-01T00:00:00Z"
}
These values are returned, but when I update the page they are lost.
This is the component that makes the request to obtain the project data:
export default {
components: { EditProject },
setup() {
const route = useRoute();
const project = reactive({});
onMounted(() => {
fetch(`http://localhost:8000/api/v1/projects/${route.params.id}`)
.then((res) => res.json())
.catch((error) => console.error(error))
.then((data) => {
Object.assign(project, data);
});
});
return {
project,
};
},
};
</script>
And this is the component which receives the information to be able to update the data:
<script>
import { ref, toRef, toRefs } from '#vue/reactivity';
import { useRoute, useRouter } from 'vue-router';
export default {
props: {
project: {
type: Object,
required: true,
},
},
setup(props) {
const project = toRefs(props.project);
console.log(project);
const content = toRef(props, 'project');
const name = toRef(content.value, 'name');
const description = toRef(content.value, 'description');
const endProject = toRef(content.value, 'endProject');
const user = toRef(content.value, 'user');
const users = ref();
const route = useRoute();
const router = useRouter();
fetch(`http://localhost:8000/api/v1/users/selected_user`)
.then((data) => data.json())
.catch((error) => console.error(error))
.then((response) => {
users.value = response;
});
const editProject = () => {
if (
name.value === '' ||
description.value === '' ||
endProject.value === '' ||
user.value === ''
) {
console.log('error');
return;
}
fetch(`http://localhost:8000/api/v1/projects/${route.params.id}`, {
method: 'PUT',
body: JSON.stringify({
name: name.value,
description: description.value,
end_date: new Date(endProject.value.replace('-', '/')),
user: {
id_user: user.value,
},
}),
headers: {
'Content-Type': 'application/json',
},
});
router.push({
name: 'Project',
});
};
return {
name,
description,
endProject,
user,
users,
editProject,
};
},
};
</script>
This is the sample code to display the data by console:
const end_date = toRefs(props.project, 'end_date');
console.log(end_date);
What it shows me by console is the following:
created_at: ObjectRefImpl {_object: Proxy, _key: "created_at", __v_isRef: true}
description: ObjectRefImpl {_object: Proxy, _key: "description", __v_isRef: true}
end_date: ObjectRefImpl
__v_isRef: true
_key: "end_date"
_object: Proxy {id_project: 3, name: "gbhnju", description: "derftgyh", start_date: "2021-08-06T00:00:00Z", end_date: "2021-08-17T00:00:00Z", …}
value: "2021-08-17T00:00:00Z"
[[Prototype]]: Object
id_project: ObjectRefImpl {_object: Proxy, _key: "id_project", __v_isRef: true}
name: ObjectRefImpl {_object: Proxy, _key: "name", __v_isRef: true}
progress: ObjectRefImpl {_object: Proxy, _key: "progress", __v_isRef: true}
project_state: ObjectRefImpl {_object: Proxy, _key: "project_state", __v_isRef: true}
start_date: ObjectRefImpl {_object: Proxy, _key: "start_date", __v_isRef: true}
updated_at: ObjectRefImpl {_object: Proxy, _key: "updated_at", __v_isRef: true}
user: ObjectRefImpl {_object: Proxy, _key: "user", __v_isRef: true}
user_creation: ObjectRefImpl {_object: Proxy, _key: "user_creation", __v_isRef: true}
But when I want to show the value of the toRef by console it generates an undefined one, or if I update the page the obtejo is as if it were lost:
console.log(end_date.value);
This is what it shows me when I update the page:
[[Prototype]]: Object
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
Related
In an admin profile, I have a list where I display the session history. I created a button to delete all sessions where isActive = false. To see the result I have to refresh my page. I want the data updated dynamically.
I'm trying to use a forEach loop to check if session isActive = false, delete the session and update sessions.
Here it's what I have done but it only removes 2-3 raw of sessions. It should remove ALL inactive sessions.
import { defineStore } from "pinia";
import axios from "axios";
export const useAuthenticationStore = defineStore({
id: "authenticationStore",
state: () => ({
session: null,
sessions: [],
loaders: {
login: false,
logout: false,
retrieveSession: false,
retrieveSessions: false,
deleteInactiveSessions: false,
},
}),
getters: {
admin: (state) => state.session?.admin,
},
actions: {
async deleteInactiveSessions(id) {
const apiRoute = `/api/inactive-sessions`;
try {
this.loaders["deleteInactiveSessions"] = true;
const deletedInactiveSessions = await axios.delete(apiRoute);
console.log(deletedInactiveSessions);
this.sessions.forEach(() => {
const deletedInactiveSessionsIndex = this.sessions.findIndex(
(session) => session.id === deletedInactiveSessions.id
);
return this.sessions.splice(deletedInactiveSessionsIndex);
});
} finally {
this.loaders["deleteInactiveSessions"] = false;
}
},
This is what deletedInactiveSessions returns me:
{data: {…}, status: 200, statusText: 'OK', headers: AxiosHeaders, config: {…}, …}
config
:
{transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
data
:
{count: 3}
headers
:
AxiosHeaders {access-control-allow-credentials: 'true', access-control-allow-origin: '*', connection: 'close', content-length: '11', content-security-policy: "default-src 'self';base-uri 'self';block-all-mixed… https: 'unsafe-inline';upgrade-insecure-requests", …}
request
:
XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status
:
200
statusText
:
"OK"
[[Prototype]]
:
Object
I am learning vuejs and i am working on my first project which is a social network, and i want to implement a like button that call the api to add a like or remove it if the user has already liked it. It does work in my backend but i can't make it work in the front.
I need to send the userId and add or remove the like when i click on the button
This is the data
data() {
return {
post: {
file: "",
content: "",
likes: 0,
},
showModal: false,
showModifyPost: false,
user: {
firstname: "",
lastname: "",
_id: "",
},
};
},
the last method i tried
likePost(id) {
axios
.post('http://127.0.0.1:3000/api/post/like/' + id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then(() => {
console.log("response", response);
this.user._id = response.data._id;
if(post.usersLiked == user._id) {
this.post.likes += 0
} else if (post.usersLiked != user._id) {
this.post.likes += 1
};
})
.catch((error) => console.log(error));
}
and this is the model
const postSchema = mongoose.Schema({
userId: { type: String, required: true, ref: "User" },
content: { type: String, required: true, trim: true },
imageUrl: { type: String, trim: true },
likes: { type: Number, default: 0 },
usersLiked: [{ type: String, ref: "User" }],
firstname: {type: String, required: true, trim: true },
lastname: {type: String, required: true, trim: true },
created_at: { type: Date},
updated_at: { type: Date }
});
Any idea what is wrong ? Thank you !
.then(() => { // you missed value response from Promise here
this.user._id = response.data._id;
if(post.usersLiked == user._id)
})
Do you mean this.post.usersLiked === user._id I suppose, so post within your data options should be
post: {
file: "",
content: "",
likes: 0,
usersLiked: false,
// something else reflect to your post schema
},
i want to implement a like button that call the api to add a like or remove it if the user has already liked it
By saying that you just need a simple boolean value to do this
likePost(id) {
axios
.post('http://127.0.0.1:3000/api/post/like/' + id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then((response) => {
// Just need to toggle state
this.$set(this.post, 'usersLiked', this.post.usersLiked !== response?.data?._id)
})
.catch((error) => console.log(error));
}
Found the answer, i changed the axios method to this
likePost(id) {
let userId = localStorage.getItem('userId');
axios
.post('http://127.0.0.1:3000/api/post/like/' + id, { userId }, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then((response) => {
console.log(response.data);
this.getAllPost();
})
.catch((error) => console.log(error));
}
i also made a few changes to the data
data() {
return {
posts: [],
post: {
file: "",
content: "",
},
showModal: false,
showModifyPost: false,
user: {
firstname: "",
lastname: "",
_id: "",
},
};
},
and i also made some changes on the controller
exports.ratePost = (req, res, next) => {
console.log(req.body.userId)
//using findOne function to find the post
Post.findOne({ _id: req.params.id }).then(post => {
if (!post.usersLiked.includes(req.body.userId)) {
// making a object with $inc and $push methods to add a like and to add the user's id
let toChange = {
$inc: { likes: +1 },
$push: { usersLiked: req.body.userId },
};
// we update the result for the like
Post.updateOne({ _id: req.params.id }, toChange)
// then we send the result and the message
.then(post =>
res
.status(200)
.json(
{ message: "Liked !", data: post }
)
)
.catch(error => res.status(400).json({ error }));
} else if (post.usersLiked.includes(req.body.userId)) {
// using the updateOne function to update the result
Post.updateOne(
{ _id: req.params.id },
// we use a pull method to take off a like
{ $pull: { usersLiked: req.body.userId }, $inc: { likes: -1 } }
)
.then(post => {
// then we send the result and the message
res
.status(200)
.json(
{ message: "Post unliked", data: post }
);
})
.catch(error => res.status(400).json({ error }));
}
});
};
I am currently uploading videos and images using base64 encoding but it was highly recommended to use an alternative to this. I am using RNFetchBlob to read the encoded file and then attach it to SuperAgent for uploading. I have seen some examples of using FormData to attach the file but cannot find a complete working example. If someone could provide a code example on how to achieve this I would greatly appreciate it.
RNFetchBlob.fs.readFile(filePath, 'base64')
.then((base64data) => {
let base64Image = `data:video/mp4;base64,${base64data}`;
let uploadRequest = superagent.post(uploadURL)
uploadRequest.attach('file',base64Image)
Object.keys(params).forEach((key) => {
uploadRequest.field(key,params[key])
})
uploadRequest.on('progress', function(e) {
this.props.setVideoUploadProgress(e.percent)
}.bind(this))
uploadRequest.end((err,resp) => {
})
})
I am using react-native-image-picker to allow users to select or record a video, which gives me a URI of the video file path. Then I use RNFetchBlob to upload it to the server.
RNFetchBlob.fetch('POST', 'Upload API endpoint', {
...this.getHeader(),
'Content-Type': 'multipart/form-data'
// Change BASE64 encoded data to a file path with prefix `RNFetchBlob-file://`.
// Or simply wrap the file path with RNFetchBlob.wrap().
}, [
// element with property `filename` will be transformed into `file` in form data
{ name: 'file', filename: 'video.mp4', data: RNFetchBlob.wrap(this.state.videoUri) },
// custom content type
]).uploadProgress({ interval: 250 }, (written, total) => {
let uploaded = (written / total) * 100
this.setState({
uploadProgress: uploaded.toFixed(1)
})
})
.then((response) => {
if (response.ok) {
this.setState({
uploading: false,
uploadSuccess: true,
uploadFailed: false,
})
}
}).catch((err) => {
this.setState({
uploading: false,
uploadSuccess: false,
uploadFailed: true,
})
})
Basically you have to give the path of your image, audio or video to fetch blob. The following code worked for me:
RNFetchBlob.fetch(
'POST',
`${BASE_URL}vehicle/vehicleRegistration`,
{
Authorization: 'Bearer ' + authToken,
'Content-Type': 'multipart/form-data,octet-stream',
},
[
{
name: 'photo',
filename: 'vid.mp4',
data: RNFetchBlob.wrap(vehicleImage.uri),
},
{
name: 'email',
data: user.email,
},
{
name: 'userId',
data: user.id,
},
{
name: 'vehicleType',
data: values.vehicleType,
},
{
name: 'make',
data: values.make,
},
{
name: 'buildYear',
data: values.buildYear,
},
{
name: 'model',
data: values.model,
},
{
name: 'nickName',
data: values.nickName,
},
{
name: 'engineSize',
data: values.engineSize,
},
],
)
.uploadProgress((written, total) => {
console.log('uploaded', written / total);
})
.then(response => response.json())
.then(RetrivedData => {
console.log('---retrieved data------', RetrivedData);
Toast.show({
text1: 'Success',
text2: 'Vehicle Added to Garage!',
type: 'success',
});
})
.catch(err => {
console.log('----Error in adding a comment----', err);
Toast.show({
text1: 'Request Failed',
text2: err?.response?.data?.message,
type: 'error',
});
});
Trying to write a test for a nested model but can't get it working:
Model:
const EmployeeSchema = new mongoose.Schema({
firstName: {type: String, required: true},
lastName: { type: String, required: true}
});
const CompanySchema = new mongoose.Schema({
name: { type: String, required: true },
streetAddress: { type: String, required: true },
country: { type: String, required: true },
employees:[EmployeeSchema]
}, { timestamps: true});
Controller:
function create(req, res, next) {
const company = new Company({
name: req.body.name,
streetAddress: req.body.streetAddress,
country: req.body.country
});
company.employees.push(req.employees);
company.save()
.then(savedCompany => res.json(savedCompany))
.catch(e => next(e));
}
Test:
describe('## Company APIs', () => {
let company = {
name: "Test Company",
streetAddress: "123 Fake Street",
country: "A Country"
};
company.employees.push({firstName: "Jane", lastName: "Doe"});
describe('# POST /api/company', () => {
it('should create a new company', (done) => {
request(app)
.post('/api/company')
.send(company)
.expect(httpStatus.OK)
.then((res) => {
expect(res.body.name).to.equal(company.name);
expect(res.body.streetAddress).to.equal(company.streetAddress);
expect(res.body.country).to.equal(company.country);
company = res.body;
done();
})
.catch(done);
});
});
The above gives: TypeError: Cannot read property 'push' of undefined
I've tried a few other things but this is the most promising result, for some reason I just can't seem to populate the embedded model as part of setting up the unit test.
I ended up resolving this, hopefully this helps someone in the future.
Test:
it('should associate an employee with the company', (done) => {
var employee = new Employee();
company.employees.push(employee);
request(app)
.put(`/api/company/${company._id}`)
.send(company)
.expect(httpStatus.OK)
.then((res) => {
expect(res.body.employees).to.be.an('array')
expect(res.body.employees).to.contain(employee.id)
done();
})
.catch(done);
});
Controller:
Adding this to handle multiple additions:
if (req.body.employees != null) {
req.body.employees.forEach(function(employee) {
company.employees.push(employee);
}, this);
}
I'm trying to call a mocked service and update the user variable, but when I call the mocked service nothing changes?
I am generally struggling with testing, if there are any good resources to learn with angular2 I'm all ears.
let users = [{ name: 'Test', lastname: 'User' }, { name: 'Test2', lastname: 'User2' }];
let addedUsers = [{ name: 'blah', lastname: 'blah' },{ name: 'Test', lastname: 'User' }, { name: 'Test2', lastname: 'User2' }];
describe('Component: UserList', () => {
beforeEach(() => {
userServiceStub = {
getUsers: () => {
return Observable.of(users);
},
getUser: () => {
return Observable.of(user);
},
addUser: () => {
users.push({ name: 'blah', lastname: 'blah' });
}
};
TestBed.configureTestingModule({
declarations: [UserListComponent],
imports: [HttpModule],
providers: [
{provide: UsersService, useValue: userServiceStub },
{ provide: Router, useClass: RouterStub }
]
});
app = fixture.debugElement.componentInstance;
userService = fixture.debugElement.injector.get(UsersService);
it('should call addUser on button click', () => {
let spy = spyOn(userService, 'addUser');
userService.addUser('argument');
fixture.detectChanges();
expect(users).toEqual(addedUsers);
});
});