How to display time ago when specific table columns updated? - reactjs

I want to show the time ago when the latitude and longitude last updated in my table.
My code currently shows the time ago of last update (through web
socket). It doesn't show the time ago that the latitude or longitude specifically were updated. How can I solve this? Here is a screen-shot of the table, and the code is below:
componentDidMount() {
let socket = new WebSocket('ws://139.162.2.53:9988');
this.setState({ socket: socket });
this.getSupportInfo();
socket.onmessage = ((message) => {
let socketData = JSON.parse(message.data);
//console.log(socketData[0] );
let device_id = socketData[0].device_id;
let updatedSupportInfo = this.state.supportInfo;
let now = new Date();
let uSupport = updatedSupportInfo.map(function(item){
if(device_id == item.device_id){
// console.log(item);
item.current_pos = socketData[0].current_pos;
item["latlng"] = item.current_pos.x + ',' + item.current_pos.y;
let time = new Date(socketData[0].timestamp)
let a = moment(time);
let b = moment(now);
//let timeAgo = a.from(b);
let timeAgo = b.diff(a, 'minutes')
//console.log("a", a);
//console.log("b", b);
//console.log("timeAgo", timeAgo);
item["timeAgo"] = timeAgo;
}
return item;
});
this.setState({supportInfo:uSupport})
});
}
I am using react bootstrap table:
<TableHeaderColumn dataField="timeAgo" dataSort={true}>Time Ago(mins)</TableHeaderColumn>

Related

Firebase's onValue only get data once and does not update when placed inside a loop in React's useEffect

My goal is to get multiple data based on a list of data the customer requested so I put the codes inside useEffect. If the array contains the list of things the customer wants, then it grab those data from the server so the user can manipulate it. So far, it works fine but when the database updates, onValue is not triggered to grab the new data to update the render.
Here is my code. Thank you for helping me in advance.
// Getting data
useEffect(() => {
if (empDataArr.length > 1) {
let fromDay = parseInt(dateHandler(startDate).dateStamp);
let toDay = parseInt(dateHandler(endDate).dateStamp);
let tempLogArr = [];
empDataArr.forEach((emp) => {
let qLogEvent = query(child(shopRef(shopId), emp.id + "/log_events"), orderByChild("dateStamp"), startAt(fromDay), endAt(toDay));
// This is the part I need help
onValue(qLogEvent, (snap) => {
let logEventArr = [];
let val = snap.val();
if (val === null) {
} else {
Object.keys(val).forEach((key) => {
let id = key;
let dateStamp = val[key].dateStamp;
let direction = val[key].direction;
let time = val[key].timeStamp + "";
let timeStamp = time.substring(8, 10) + ":" + time.substring(10, 12);
logEventArr.push({ direction: direction, timeStamp: timeStamp, dateStamp: dateStamp, id: id });
});
tempLogArr.push({
id: emp.id,
logEvent: logEventArr,
});
}
});
});
setLogDataArr(tempLogArr.map((x) => x));
}
}, [empDataArr, shopId, startDate, endDate]);
useEffect(() => {
console.log(logDataArr);
}, [logDataArr]);
I have tried using return onValue() and const logData = onValue() but they do not work (and I do not expect the former one to work either).

Exact Time Ago is not coming form moment js

I am doing my project in reactjs and i want time ago to show in table.i am using moment js to show time ago(fromNow()) but it shows the time few second only when the data comes from server.And it shows directly 6hrs ago if the data are not coming from server.Eg afer 2minutes of time interval it shows 6 hours ago.As shown in table below.
the code of my project is shown below
componentDidMount() {
let socket = new WebSocket('wss://api.example.com.np/ws');
this.setState({ socket: socket,noOfVehicle:this.state.supportInfo.length });
this.getSupportInfo();
socket.onmessage = ((message) => {
let socketData = JSON.parse(message.data);
let device_id = socketData[0].device_id;
let updatedSupportInfo = this.getUpdatedInfo(this.state.sourceName);
let flag = true;
let uSupport = updatedSupportInfo.map(function(item){
if(device_id == item.device_id){
item.current_pos = socketData[0].current_pos;
if(item.current_pos){
flag = true;
item["latlng"] = item.current_pos.x + ',' + item.current_pos.y;
}else{
flag = false;
}
let time = new Date(socketData[0].timestamp);
let now = new Date();
let timeAgoIn = moment(time).fromNow(true);
item["timeAgoIn"] = timeAgoIn;
}
getSupportInfo() {
axios({
method: 'get',
url: 'https://support.taranga.com.np/support_info'
})
.then((response) => {
for (var i = 0; i < response.data.length; i++) {
if(response.data[i].current_pos){
response.data[i]["latlng"] = response.data[i].current_pos.x + ',' + response.data[i].current_pos.y;
let time = new Date(response.data[i].timestamp)
let now = new Date();
let a = moment(time);
let b = moment(now);
let timeAgo = b.diff(a, 'hours')
let timeAgoIn = moment(time).fromNow(true)
response.data[i]["timeAgo"] = timeAgo;
response.data[i]["timeAgoIn"] = timeAgoIn;
}
}
this.setState({
supportInfo: response.data
});
})
.catch((error)=>{
throw (error);
});
}
getUpdatedInfo(name) {
let uInfo = [];
let tempSupport = this.state.supportInfo.slice();
_.map(tempSupport,(value,key) =>{
if(value.timeAgo !=0){
let time = new Date(value.timestamp)
let now = new Date();
let a = moment(time);
let b = moment(now);
let timeAgo = b.diff(a, 'minutes')
console.log(timeAgo);
//let timeAgo = moment.duration(b-a).humanize()
let timeAgoIn = moment(time).fromNow(true)
value["timeAgo"] = timeAgo;
value["timeAgoIn"] = timeAgoIn;
}
});
this.setState({
supportInfo:tempSupport
});
the code to show in table is
<TableHeaderColumn dataField="timeAgoIn" dataSort={true}>Time Ago</TableHeaderColumn>
I believe your logic is flawed, when you get the info you are storing the timeAgo once, however timeAgo is a property that changes over time, ex:
You receive a message at 12:00, you set timeAgo to 1 second (or w/e js sets it to)
You check your screen at 12:05, timeAgo for that message is still 1 second, because this is calculated once, but time has passed and timeAgo should be 5 seconds ago, right?
timeAgo property should remain as the timestamp you received from server and be calculated when you refresh your table (when you want to do this is a different topic)

Adding check boxes in AmCharts

I am working o an AngularJs Application where I am using AmCharts.
const writeemp = data => {
const {
total,
employees,
} = data;
empChart.dataProvider = e;
empChart.write('emp');
empChart.validateData();
};
AmCharts.handleLoad();
var configChart = function () {
empChart = new AmCharts.AmSerialChart();
empChart.categoryField = "state";
empChart.labelRotation = 90;
var yAxis = new AmCharts.ValueAxis();
yAxis.position = "left";
empChart.addValueAxis(yAxis);
empBarGraph = new AmCharts.AmGraph();
empBarGraph.valueField = "count";
empBarGraph.type = "column";
empBarGraph.fillAlphas = 1;
empBarGraph.lineColor = "#f0ab00";
empBarGraph.valueAxis = yAxis;
empChart.addGraph(empBarGraph);
empChart.write('empChart');
$http.get(hostNameService.getHostName()+"/dashboard/employees/statecount")
.then(response => writeemp(response.data));
}
Code in html:
<div class='panel-body'>
<div id="empChart"></div>
</div>
This would return me the values of State on x-axis and count on y-axis. I wanted to add checkboxes which would filter my data in the chart. Each check box should represent the 'state' of the employee. If I uncheck a box then the data displayed should change in the chart. Can anyone let me know how I could achieve this.

amCharts not displaying when the page loads in AngularJs

I am using amCharts to display some data and calling this in my init function. The following is my code:
export default class ACtrl {
constructor($scope, $http, $state) {
var sampleCharts = function () {
let sampleChart;
let sampleBarGraph;
let sampleLine;
const writeAlarmsample = data => {
const {
total,
users
} = data;
// Set cumulative percentage
let runningTotal = 0;
users.forEach(user => {
runningTotal += user.assetAvailability;
user.cumulativePercentage = runningTotal / total * 100;
});
sampleChart.dataProvider = users;
sampleChart.write('userAvailability');
sampleChart.validateData();
};
function handleClick(event){
$state.go("app.userdetails", { userID: event.item.category });
}
// Alarm sample
AmCharts.ready(() => {
sampleChart = new AmCharts.AmSerialChart();
sampleChart.categoryField = "assetId";
//add click listener
sampleChart.addListener("clickGraphItem", handleClick);
var yAxis = new AmCharts.ValueAxis();
yAxis.position = "left";
sampleChart.addValueAxis(yAxis);
var yAxis2 = new AmCharts.ValueAxis();
yAxis2.position = "right";
sampleChart.addValueAxis(yAxis2);
sampleBarGraph = new AmCharts.AmGraph();
sampleBarGraph.valueField = "userAvailability";
sampleBarGraph.type = "column";
sampleBarGraph.fillAlphas = 1;
sampleBarGraph.lineColor = "#f0ab00";
sampleBarGraph.valueAxis = yAxis;
sampleChart.addGraph(sampleBarGraph);
sampleLine = new AmCharts.AmGraph();
sampleLine.valueField = "cumulativePercentage";
sampleLine.type = "line";
sampleLine.lineColor = "#cb0044";
sampleLine.valueAxis = yAxis2;
sampleChart.addGraph(sampleLine);
sampleChart.write('userAvailability');
$http.get(constants.LOCAL_HOST+"/dashboard/users")
.then(response => writeAlarmsample(response.data));
});
};
$scope.init = function() {
availabilityCharts();
};
})
}
The charts load fine when I hit the refresh button, but they are not loaded when the page gets loaded for the first time. I also have a refresh button which calls the function to load the charts even that does not load the charts. If I click on one of the chart items it takes me to details page and when I come back to this page the charts do not load. I have to click on refresh again to load the charts. Can anyone let me know what is the reason for this issue and how I can fix it.

Swift array. trying to find the next time in array based on current time

I have the current time and this array of times. I would like to work out which is the closest next time to the current time.
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Hour, .Minute], fromDate: date)
let hour = components.hour
let minutes = components.minute
let currentTime = "\(hour)" + ":" + "\(minutes)" //output 15:24
let timesArray = ["5:45", "6:35", "7:00", "7:30", "7:50", "8:20", "8:40", "9:15", "10:10", "11:10", "12:40", "14:15", "14:50", "15:40", "16:10", "17:10", "17:40", "18:40", "19:25", "20:50"]
let date = NSDate()
let timesArray = ["5:45", "6:35", "7:00", "7:30", "7:50", "8:20", "8:40", "9:15", "10:10", "11:10", "12:40", "14:15", "14:50", "15:40", "16:10", "17:10", "17:40", "18:40", "19:25", "20:50"]
// create a method to convert your time to minutes
func stringToMinutes(input:String) -> Int {
let components = input.componentsSeparatedByString(":")
let hour = Int((components.first ?? "0")) ?? 0
let minute = Int((components.last ?? "0")) ?? 0
return hour*60 + minute
}
//create an array with the minutes from the original array
let timesMinutesArray:[Int] = timesArray.map { stringToMinutes($0) }
let dayMinute = stringToMinutes("15:24")
// filter out the times that has already passed
let filteredTimesArray = timesMinutesArray.filter{$0 > dayMinute }
// get the first time in your array
if let firstTime = filteredTimesArray.first {
// find its position and extract it from the original array
let item = timesArray[timesMinutesArray.indexOf(firstTime)!] // "15:40"
}
If you need you can also create an extension to use it anywhere in your code as follow:
extension String {
var hourMinuteValue: (hour:Int,minute:Int) {
guard
let hour = Int(componentsSeparatedByString(":").first ?? ""),
let minute = Int(componentsSeparatedByString(":").last ?? "")
where componentsSeparatedByString(":").count == 2
else { return (0,0) }
return (hour,minute)
}
var dayMinute:Int {
return hourMinuteValue.hour*60 + hourMinuteValue.minute
}
}
let time = "15:24"
let times = ["5:45", "6:35", "7:00", "7:30", "7:50", "8:20", "8:40", "9:15", "10:10", "11:10", "12:40", "14:15", "14:50", "15:40", "16:10", "17:10", "17:40", "18:40", "19:25", "20:50"]
let minutes = times.map{ $0.dayMinute }
let filteredMinutes = minutes.filter{ $0 > time.dayMinute }
if let firstTime = filteredMinutes.first {
let item = times[minutes.indexOf(firstTime)!] // "15:40"
}

Resources