Vue delete current data values after #changed from select box - javascript

I have a query that gets a record and display it to a graph. I can already display the records but when I click a record without a result and then click the previous with a result. The data property in vue adds the current result resulting to append the previous one. What I want is when I select another option from the select tag, the current data will be deleted and will be replaced with the current result with the new one.
Here is my Graph
When i clicked Vince from the select box I got the exact data and the graph. here is my Vue devtools details
But when I click mark the second teacher which has NO data or result
the data from my previous array is still in there and when I click back to vince which has a data in it here is the result
and the graph is like this
My code right now is which is not working
getdata() {
let self = this
axios.get('/getGraph/' + self.teacher)
.then(({
data
}) => {
if(data.length > 0){
data.splice()
}
else{
data.date.forEach(x => {
self.dataSource.data.push(x);
});
}
})
}
My original code is this
getdata() {
let self = this
axios.get('/getGraph/' + self.teacher)
.then(({
data
}) => {
data.date.forEach(x => {
self.dataSource.data.push(x);
});
})
},
getTeachers() {
axios.get('getTeachers')
.then((res) => {
this.teachers = res.data
})
.catch((e) => {
console.log(e)
})
}
Could someone tell me what is wrong and how could I achieve what i want to do? Thanks a lot.

You have to clear your data everty time you recieved data from the server like this one.
axios.get('/getGraph/' + self.teacher)
then(({
data
}) => {
self.dataSource.data = []
data.date.forEach(x => {
self.dataSource.data.push(x);
});
})

Related

Compare two Session ID's in Cypress

I am new to automation and coding in general and I would like to compare two session ID values with the following steps:
Get first value right after logging in
Refresh page
Get second value and make an assertion.
I made a custom command in order to simplify things:
Cypress.Commands.add('getSessionId', () => {
let sessionId
cy.getCookie('development')
.its('value').then(($value) => {
sessionId = String($value)
})
})
I want the test script to look something like this:
let firstSessionId = cy.getSessionId()
cy.reload()
let secondSessionId = cy.getSessionId()
expect(firstSessionId).to.eq(secondSessionId)
There are two problems with this:
I cannot access the values as strings in this scenario
The expect runs before getting the ID's (i guess because of the asyncronous nature of cypress?)
I would appreciate any hint what I do wrong. Thanks
This is the simplest way to perform the test, no need for a custom command in this case.
cy.getCookie('development').its('value')
.then(sessionId1 => {
cy.reload()
cy.getCookie('development').its('value')
.then(sessionId2 => {
expect(sessionId1).to.eq(sessionId2)
})
})
If you want a custom command for other reasons,
Cypress.Commands.add('getSessionId', () => {
cy.getCookie('development').its('value') // last command is returned
})
cy.getSessionId().then(sessionId1 => {
cy.reload()
cy.getSessionId().then(sessionId2 => {
expect(sessionId1).to.eq(sessionId2)
})
})
You can return the value from the custom command like this:
Cypress.Commands.add('getSessionId', () => {
cy.getCookie('development')
.its('value')
.then((val) => {
return cy.wrap(val)
})
})
Then in your test, you can do this:
//Get First session Id
cy.getSessionId.then((sessionId1) => {
cy.wrap(sessionId1).as('sessionId1')
})
//Refresh Page
cy.reload()
//Get Second session Id
cy.getSessionId.then((sessionId2) => {
cy.wrap(sessionId2).as('sessionId2')
})
//Assert both
cy.get('#sessionId1').then((sessionId1) => {
cy.get('#sessionId2').then((sessionId2) => {
expect(sessionId1).to.eq(sessionId2)
})
})

How do I only render the updated stat - websockets

right now the entire div re-renders, but I am searching for a way to only re-render the updated statistic
these are parts of what I have now
updatestats.js
document.querySelector("#submit").addEventListener("click", function (e) {
let country = document.querySelector("#country").value
let numberCases = document.querySelector("#number").value
fetch(base_url + "/api/v1/stats/updatestats", {
method: "put",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"country": country,
"numberCases": numberCases
})
}).catch(err => {
console.log(err);
})
primus.write({ "action": "update" })
stats.js
primus.on("data", (json) => {
if (json.action === "update") {
document.querySelector("#overview").innerHTML = ""
appendInfo()
}
})
function appendInfo() {
fetch(base_url + "/api/v1/stats", {
method: "get",
headers: {
'Content-Type': 'application/json'
},
}).then(response => {
return response.json();
}).then(json => {
json.data.stats.forEach(stat => {
let country = stat.country
let numberCases = stat.numberCases
let p = document.createElement('p')
let text = document.createTextNode(`${country}: ${numberCases}`)
p.appendChild(text)
let overview = document.querySelector("#overview")
overview.appendChild(p)
})
}).catch(err => {
console.log(err);
})
}
window.onload = appendInfo();
stats.pug
body
h1 Cases by country
div#overview
So if I only update the country Belgium I only want that statistic to be changed. Now everything seems to reload
What I meant with my suggestion is to keep te communication of data between client and server strictly in the sockets. Meaning when one user updates 1 value on their end, that value will be send to the server and stored. After the server finished storing the value, that same value will be sent to all other clients. This way you only send and receive the parts that have been changed without having to download everything on every change.
I might not be able to write the code exactly as it should be as I have limited experience with Primus.js and know little about your backend.
But I would think that your frontend part would look something like this. In the example below I've removed the fetch function from the click event. Instead send the changed data to the server which should handle those expensive tasks.
const countryElement = document.querySelector("#country");
const numberCasesElement = document.querySelector("#number");
const submitButton = document.querySelector("#submit");
submitButton.addEventListener("click", function (e) {
let data = {
action: 'update',
country: countryElement.value,
numberCases: numberCasesElement.value
};
primus.write(data);
});
Now the server should get a message that one of the clients has updated some of the data. And should do something with that data, like storing it and letting the other clients know that this piece of data has been updated.
primus.on('data', data => {
const { action } = data;
if (action === 'update') {
// Function that saves the data that the socket received.
// saveData(data) for example.
// Send changed data to all clients.
primus.write(data);
}
});
The server should now have stored the changes and broadcasted the change to all other clients. Now you yourself and other will receive the data that has been changed and can now render it. So back to the frontend. We do the same trick as on the server by listening for the data event and check the action in the data object to figure out what to do.
You'll need a way to figure out how to target the elements which you want to change, you could do this by having id attributes on your elements that correspond with the data. So for example you want to change the 'Belgium' paragraph then it would come in handy if there is a way to recognize it. I won't go into that too much but just create something simple which might do the trick.
In the HTML example below I've given the paragraph an id. This id is the same as the country value that you want to update. This is a unique identifier to find the element that you want to update. Or even create if it is not there.
The JavaScript example after that receives the data from the server through the sockets and checks the action. This is the same data that we send to the server, but only now when everybody received we do something with it.
I've written a function that will update the data in your HTML. It will check for an element with the id that matches the country and updates the textContent property accordingly. This is almost the same as using document.createTextNode but with less steps.
<div id="overview">
<p id="Belgium">Belgium: 120</p>
</div>
const overview = document.querySelector("#overview");
primus.on('data', data => {
const { action } = data;
if (action === 'update') {
updateInfo(data);
}
});
function updateInfo(data) {
const { country, numberCases } = data;
// Select existing element with country data.
const countryElement = overview.querySelector(`#${country}`);
// Check if the element is already there, if not, then create it.
// Otherwise update the values.
if (countryElement === null) {
const paragraph = document.createElement('p');
paragraph.id = country;
paragraph.textContent = `${country}: ${numberCases}`;
overview.append(paragraph);
} else {
countryElement.textContent = `${country}: ${numberCases}`;
}
}
I hope that this is what you are looking for and / or is helpful for what you are trying to create. I want to say again that this is an example of how it could work and has not been tested on my end.
If you have any questions or I have been unclear, then please don't hesitate to ask.
To elaborate #EmielZuurbier's suggestion in the comment, please try the following code.
//Client-side
primus.emit('data',data);
primus.on("dataUpdated", (json) => {
});
//Server-side
primus.on('data',data =>{
//process it here and then
//send it out again
primus.emit('dataUpdated','the data you want to send to the front end');
})

How to sort data in JQuery

I'm working on a slider which is showing data from the backend. Using the "push" function it is showing slides in the slider according to date. But I need it to show these slides according to date & status.
Firstly show incomplete status (btn-danger), after it show pending status (btn-success), and then completed status (btn-warning).
screenshot of code https://ibb.co/5KJpdrh
full code:
paste.ofcode.org/hmKSwTvaWrjTj3A6rWh464
code:
function handleSubmit(command) {
if(command === 'meeting') {
let meetingFormValue = getMeetingFormValue('.create-meeting-form');
httpService.post('http://localhost:3000/meeting/create', meetingFormValue)
.then(response => {
meetings.push(response);
setMeetingCarausel();
}).catch(ex => {
console.log('Error');
console.log(ex);
})
// close the form
$('.create-meeting-form').stop().slideToggle();
}else if(command === 'task') {
//attendees
const taskFormValue = getTaskFormValue('#createTaskForm');
httpService.post('http://localhost:3000/meeting/taskList/create', taskFormValue)
.then(response => {
tasks.push(response);
setTasksCarausel();
}).catch(ex => {
console.log(ex);
});
// close the form
$('.create-task-form').stop().slideToggle();
}
}
You want to use Array.prototype.sort().
You should pass a compare function to have sort() use your criteria to sort your entries properly.

Angular clear array

I am trying to refresh my page on delete and refresh button, it gets new data but the issue is new data will add to old ones I need to clear old data before adding new data.
Code
addresses: any[] = [];
// loads first time data
this.addressService.getAddresses().subscribe((res) => {
for (let address of res['data']) {
this.addresses.push(address);
}
this.hideLoading();
});
// refresh list items
doRefresh(event) {
console.log('Begin async operation');
setTimeout(() => {
console.log('Async operation has ended');
// get new items in list
this.addressService.getAddresses().subscribe((res) => {
for (let address of res['data']) {
this.addresses.push(address);
}
this.hideLoading();
});
event.target.complete();
}, 2000);
}
//remove item and renew list items
removeAddress(id: string){
this.addressService.remove(id).subscribe(
data => {
this.alertService.presentToast(data['message']);
//getting items (renew)
this.addressService.getAddresses().subscribe((res) => {
for (let address of res['data']) {
this.addresses.push(address);
}
this.hideLoading();
});
},
error => {
this.alertService.presentToast(error['message']);
}
);
}
I think that I need to clear addresses: any[] = []; before getting
new items in my doRefresh(event){..} and removeAddress(id:
string){...} functions to avoid duplicates.
Any idea?
Assuming your refresh function works,
add this code before you get new items from your api
this.addresses =[];
or
this.addresses.length = 0;
For implementation wise, in regards to delete function, you can delete from your backend , clear your array and pull a fresh set of data which might be costly if you have a huge dataset.
You might want to consider updating your backend (delete that specific data) and removing that specific index from your array (when your delete function returns success)
For update, you can do a comparison and update those those array objects that has been modified. Else you can just clear your array and retrigger your retrieve api function.

Cannot access a key value pair of a changed object

Please excuse my code
From an external source , I am given the following external data which I name loxAP3
to which I am trying to firstly retrieve svg data related to the rooms.image property and then change the incoming svg data to work with react, using the following code.
createRoomData(loxAPP3, socket) {
console.log(loxAPP3)
let rooms = []
let rawRooms = loxAPP3.rooms
for (const rawRoom in rawRooms) {
rooms.push(rawRooms[rawRoom])
}
//add svg property with blank property value
rooms.forEach((room) => {
room.svg = ''
})
//fetch image data for each room in loxApp3.rooms
rooms.forEach((room) => {
const image = room.image
socket
.send(image)
.then(function(respons) {
//console.log("Successfully fetched svg image " + respons ); // success
room.svg = respons
//console.log(room.svg) // success console returns room.svg data
},
function(err) {
console.error(err);
}
);
})
this.setState({
rooms: rooms
}, () => {
console.log(rooms) // success rooms[0].svg is shown as having been populated
this.adjustSvGImageToReact()
})
}
console.log(rooms) // success rooms[0].svg is shown as having been populated
However the problem comes when I try and manipulate the room object, if I log a property that already existed from the original data, there is no problem, however if I try an fetch the .svg property it comes back not as undefined but as the empty string I first set it to be.
adjustSvGImageToReact() {
this.state.rooms.forEach((room)=>{
console.log(room.name) // success
console.log(room.uuid) // success
console.log(room.svg) //empty
})
}
Create an array of the socket.send() promises instead of calling them inside forEach
Then you can use Promise.all() to set the state and call adjustSvGImageToReact() after the socket requests have completed
const svgPromises = rooms.map((room) => {
const image = room.image
return socket
.send(image)
.then((respons)=> room.svg = respons)
})
Promise.all(svgPromises).then(() => {
this.setState({rooms: rooms}, () => {
console.log(rooms) // success rooms[0].svg is shown as having been populated
this.adjustSvGImageToReact()
});
}).catch(err=>console.log('One of the socket requests failed'))

Categories