How to find duration from google fit api in ionic4? - ionic4

I am developing fitness app using google fit APIs. In which I am calculating distance, steps, calories and duration. All the details have been found apart from duration. How can I find duration using google fit api ?
Thanks in advance.

From googleFit api, you will find startDate and endDate.
You will have to get the time difference and add them together.
First import googlefit service:
import { GoogleFitService } from "../../core/services/google-fit.service";
Declare it into constructor:
constructor(
private googleFit: GoogleFitService
) { }
Get duration data:
this.googleFit.query().then(res => {
let totalDiff = 0;
for (let i = 0; i < res.length; i++) {
totalDiff =
totalDiff +
(res[i].endDate.getTime() -
res[i].startDate.getTime()); // milliseconds
}
let seconds: any = (totalDiff / 1000).toFixed(0);
});

Related

Moment JS seemingly returning random date

Moment JS is returning a random date.
I am trying to create a calendar in a react-native project. I created this loop to count back the days from today's date. I have attached my console and tried to clearly show how I tried to debug this.
The subtract method seems not to recognise the loop and the i value seems to stay at 16.
Any help would be greatly appreciated.
This is the code that is causing all the fussThis is the output in the console
Per Moment.js, moments are mutable. Clone the moment before performing date math
https://momentjs.com/guides/#/lib-concepts/mutability/
You'll need to create a new moment instance or clone the existing one when performing operations like .add(), .subtract(), etc.
const moment = require("moment");
const today = moment();
// count back N days
const N = 3;
let i = 1;
let days = [];
// #1 - Create a new moment instance from today and add -i days
while (i <= N) {
const day = moment(today).add(-i, "days");
days.push(day);
i++;
}
console.log("Approach #1");
console.log({ days });
// #2 - A moment is mutable. So we use add() to mutate today by -1 days each iteration, clone the instance, and push to array
i = 0;
days = [];
while (i < N) {
const day = today.add(-1, "days").clone();
days.push(day);
i++;
}
console.log("Approach #2");
console.log({ days });

How to get exact location name with lat & long google map?

I want to get location name using latitude and longitude of user like any theater, restaurant, famous park, vacation place, shopping store. I am using Google map api but they only shows area name not any store name. How I get location name?
You can use Google Places API to get this information. Google Maps will not return store or place data based on latitude and longitude parameters.
I would enable your API key to work with Google Places API and then make a call to the getNearbyPlaces endpoint. The endpoint requires latitude, longitude, and radius (distance in meters in which the results must be found) parameters. Remember, this is still a query so your response will contain multiple results and by default, the results are ordered by popularity. I like to also specify a "type=establishment" as an optional parameter so I don't get abstract results like "route".
You can test this out in RapidAPI here. I've linked you directly to the getNearbyPlaces endpoint. Just fill in your apiKey, latitude, longitude, radius (I like to keep it around 20 meters for specificity), and any other optional parameters. Click "TEST function" to see a detailed JSON response. I'll show you a screenshot of what this looks like.
In this example, I looked up the latitude and longitude for Bob's Doughnuts. Boom! My first result was in fact, Bob's Doughnuts in San Francisco. RapidAPI also lets you generate a code snippet that you can copy and paste directly into your own code. You just have to click the "CODE" button above the response, sign in, and choose the language you're using. The code snippet provided from the above call looks like:
Hope this helps! One more thing.. Since the results are ordered by popularity, the first result might not always be the ideal result. The API provides a "rankBy" parameter, but I think Google is still working out some bugs with it. In the meantime, I would build a loop that finds the closest result item by distance. All you need to do is create a distance function using the Haversine formula. I'll build you a quick function! I used the haversine formula function from this post. Heres the code.
// Still using my Bob's Doughnuts example
const startLatitude = "37.7918904"; // your original query latitude
const startLongitude = "-122.4209966"; // your original query longitude
function closestResult(results) {
let closestResult = null;
let shortestDistance = null;
for (let i = 0; i < results.length; i++) {
let location = results[i].geometry.location;
let currentDistance =
getDistanceFromLatLonInKm(startLatitude, startLongitude, location.lat, location.lng);
if (shortestDistance === null) {
closestResult = results[i];
shortestDistance = currentDistance;
} else if (currentDistance < shortestDistance) {
closestResult = results[i];
shortestDistance = currentDistance;
}
}
return closestResult;
}
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180);
}
Now your success callback can look like this:
Happy coding!

making a linegraph that shows population decay with dc.js and crossfilter

I am creating a dashboard in DC.js. One of the visualizations is a survival curve showing the percentage of survival on the y-axis and the time in weeks on the x-axis
Each record in the dataset contains a deathAfter column called recidiefNa. This shows the number of weeks after death occurred, and shows -99 for survival.
See sketches for example dataset and desired chart form:
I created this code to create the dimensions and groups and draw the desired chart.
var recDim = cf1.dimension(dc.pluck('recidiefNa'));//sets dimension
var recGroup = recDim.group().reduceCount();
var resDim = cf1.dimension(dc.pluck('residuNa'));
var resGroup = resDim.group().reduceCount();
var scChart = dc.compositeChart("#scStepChart");
scChart
.width(600)
.height(400)
.x(d3.scale.linear().domain([0,52]))
.y(d3.scale.linear().domain([0,100]))
.clipPadding(10)
.brushOn(false)
.xAxisLabel("tijd in weken")
.yAxisLabel("percentage vrij van residu/recidief")
.compose([
dc.lineChart(scChart)
.dimension(recDim)
.group(recGroup)
.interpolate("step-after")
.renderDataPoints(true)
.renderTitle(true)
.keyAccessor(function(d){return d.key;})
.valueAccessor(function(d){return (d.value/cf1.groupAll().reduceCount().value()*100);}),
dc.lineChart(scChart)
.dimension(resDim)
.group(resGroup)
.interpolate("step-after")
.renderDataPoints(true)
.colors(['orange'])
.renderTitle(true)
.keyAccessor(function(d){return d.key;})
.valueAccessor(function(d){return (d.value/cf1.groupAll().reduceCount().value()*100 );})
])
.xAxis().ticks(4);
scChart.render();
This gives the following result:
As you can see my first problem is that I need the line to extend until the y-axis showing x=0weeks and y=100% as the first datapoint.
So that's question number one: is there a way to get that line to look more like my sketch(starting on the y-axis at 100%?
My second and bigger problem is that it is showing the inverse of the percentage I need (eg. 38 instead of 62). This is because of the way the data is structured (which is somehting i rather not change)
First I tried changing the valueaccessor to 100-*calculated number. Which is obviously the normal way to solve this issue. However my result was this:
As you can see now the survival curve is a positive incline which is never possible in a survival curve. This is my second question. Any ideas how to fix this?
Ah, it wasn't clear from the particular example that each data point should be based on the last, but your comment makes that clear. It sounds like what you are looking for is a kind of cumulative sum - in your case, a cumulative subtraction.
There is an entry in the FAQ for this.
Adapting that code to your use case:
function accumulate_subtract_from_100_group(source_group) {
return {
all:function () {
var cumulate = 100;
return source_group.all().map(function(d) {
cumulate -= d.value;
return {key:d.key, value:cumulate};
});
}
};
}
Use it like this:
var decayRecGroup = accumulate_subtract_from_100_group(recGroup)
// ...
dc.lineChart(scChart)
// ...
.group(decayRecGroup)
and similarly for the resGroup
While we're at it, we can concatenate the data to the initial point, to answer your first question:
function accumulate_subtract_from_100_and_prepend_start_point_group(source_group) {
return {
all:function () {
var cumulate = 100;
return [{key: 0, value: cumulate}]
.concat(source_group.all().map(function(d) {
cumulate -= d.value;
return {key:d.key, value:cumulate};
}));
}
};
}
(ridiculous function name for exposition only!)
EDIT: here is #Erik's final adapted answer with the percentage conversion built in, and a couple of performance improvements:
function fakeGrouper(source_group) {
var groupAll = cf1.groupAll().reduceCount();
return {
all:function () {
var cumulate = 100;
var total = groupAll.value();
return [{key: 0, value: cumulate}]
.concat(source_group.all().map(function(d) {
if(d.key > 0) {
cumulate -= (d.value/total*100).toFixed(0);
}
return {key:d.key, value:cumulate};
}));
}
};
}

Calculate distance between two PFGeopoints in a NSPredicate for a Parse Query

I have a special case when I want to do something like
let predicate = NSPredicate(format:"
DISTANCE(\(UserLocation),photoLocation) <= visibleRadius AND
DISTANCE(\(UserLocation),photoLocation" <= 10)"
var query = PFQuery(className:"Photo", predicate:predicate)
Basically, I want to get all photos that are taken within 10km around my current location if my current location is also within the photo's visible radius
Also, photoLocation and visibleRadius are two columns in the database, I will supply UserLocation as a PFGeoPoint.
Is it possible to achieve this? In my opinion, I don't think that I may call, for example, photoLocation.latitude to get a specific coordinate value. May I?
I'll appreciate you a lot if this can be achieved!!
I found this at the pares.com docs here is the link
let swOfSF = PFGeoPoint(latitude:37.708813, longitude:-122.526398)
let neOfSF = PFGeoPoint(latitude:37.822802, longitude:-122.373962)
var query = PFQuery(className:"PizzaPlaceObject")
query.whereKey("location", withinGeoBoxFromSouthwest:swOfSF, toNortheast:neOfSF)
var pizzaPlacesInSF = query.findObjects()
This code fetch you all the objects that are in a rectangle area defined by the swOfSF & neOfSF objectc, where seOfSF is in the south-west corner and neOfSF is in the north-east corner.
You can make some alterations to the code and get all the objects in rectangle area that your object is in middle
i would recommend that you don't use a radius, because it will take a lot of calculations. Instead use a rectangle area (like in the code i gave you).
just calculate what is the max/min longitude & max/min latitude from your position and fetch all the objects that are in between. you can read about how to fine the min/max longitude & latitude here Link
I managed to solve it using Parse Cloud Code, here is the quick tutorial
Parse.Cloud.define("latestPosts", function(request, response) {
var limit = 20;
var query = new Parse.Query("Post");
var userLocation = request.params.userLocation;
var searchScope = request.params.searchScope;
var afterDate = request.params.afterDate;
var senderUserName = request.params.senderUserName;
query.withinKilometers("Location", userLocation, searchScope);
query.greaterThan("createdAt", afterDate);
query.notEqualTo("senderUserName",senderUserName);
query.ascending("createdAt");
query.find({
success: function(results) {
var finalResults = results.filter(function(el) {
var visibleRadius = el.get("VisibleRadius");
var postLocation = el.get("Location");
return postLocation.kilometersTo(userLocation) <= visibleRadius;
});
if (finalResults.length > limit) {
var slicedFinalResults = results.slice(0, 20);
response.success(slicedFinalResults);
} else {
response.success(finalResults);
}
},
error: function() {
response.error("no new post");
}
});
});
The code above illustrate a basic example of how to use Cloud Code. Except, I have to make sure that all the returned image are in the union of user's search scope and photo's visible circle. There are more techniques such as Promises. But for my purpose, the code above should just suffice.

How can I use the Twitter Search API to return all tweets that match my search query, posted only within the last five seconds?

I would like to use the API to return all tweets that match my search query, but only tweets posted within the last five seconds.
With Twitter's Search API, I can use the since_id to grab all tweets from a specific ID. However, I can't really see a good way to find the tweet ID to begin from.
I'm also aware that you can use "since:" in the actual query to use a date, but you cannot enter a time.
Can someone with Twitter API experience offer me any advice? Thanks for reading and your time!
http://apiwiki.twitter.com/Search-API-Documentation
This sounds like something you can do on your end, as created_at is one of the fields returned in the result set. Just do your query, and only use the ones that are within the last 5 seconds.
<script type="text/javascript" charset="utf-8">
// JavaScript Document
$(document).ready(function(){
// start twitter API
$.getJSON('http://twitter.com/status/user_timeline/YOUR_NAME.json?count=10&callback=?', function(data){
$.each(data, function(index, item){
$('#twitter').append('<div class="tweet"><p>' + item.text.linkify() + '</p><p><strong>' + relative_time(item.created_at) + '</strong></p></div>');
});
});
function relative_time(time_value) {
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset() * 60);
var r = '';
if (delta < 60) {
r = 'a minute ago';
} else if(delta < 120) {
r = 'couple of minutes ago';
} else if(delta < (45*60)) {
r = (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
r = 'an hour ago';
} else if(delta < (24*60*60)) {
r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
r = '1 day ago';
} else {
r = (parseInt(delta / 86400)).toString() + ' days ago';
}
return r;
}
String.prototype.linkify = function() {
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};// end twitter API
}); // ***** end functions *****
</script>
<div id="twitter">
Target Div
</div>
Are you trying to poll tweets in real time? Doesn't twitter have a limit on API req/hour. I think you'd hit that pretty fast.
Why don't you just make a call to the API every 5 seconds and grab the top 1 tweet.
Twitter API results are sorted by recent by default. Please see the following quote from twitter wiki :
Parameter to Twitter search API :
result_type: Optional. Specifies what type of search results you would prefer to receive.
* Valid values include:
o mixed: In a future release this will become the default value. Include both popular and real time results in the response.
o recent: The current default value. Return only the most recent results in the response.
o popular: Return only the most popular results in the response.
* Example: http://search.twitter.com/search.atom?q=Twitter&result_type=mixed
* Example: http://search.twitter.com/search.json?q=twitterapi&result_type=popular
* Example: http://search.twitter.com/search.atom?q=justin+bieber&result_type=recent
Please correct me if I am wrong anywhere.
Thanks and Regards,
Abhay Dandekar