How to convert object timestamp to firebase timestamp? - javascript

I want to convert the following timestamp:
Object {
"_nanoseconds": 725000000,
"_seconds": 1621386976,
}
to this timestamp:
t {
"nanoseconds": 725000000,
"seconds": 1621386976,
}
How can I go about doing this? I am stumped. I have tried toDate() and variations of this, but nothing is working.

Found this on reddit:
getTimeText = (timeObject: any) => {
// Convert to time text once it's of type firestore.Timestamp
const getTextFromTimestamp = (timestamp: app.firestore.Timestamp) => {
return this.timeAgo.format(timestamp.toDate())
}
if (timeObject instanceof app.firestore.Timestamp) {
// Check if Timestamp (accessed from client SDK)
return getTextFromTimestamp(timeObject)
} else if (Object.prototype.toString.call(timeObject) === '[object Object]') {
// Check if it's a Map (accessed from Cloud Functions)
const seconds = timeObject['_seconds']
const nanoseconds = timeObject['_nanoseconds']
if (seconds && nanoseconds) {
const timestamp = new app.firestore.Timestamp(seconds, nanoseconds)
return getTextFromTimestamp(timestamp)
}
}
console.log('Couldn\'t parse time', timeObject)
// Fallback
return 'some time ago'
}

Related

Instant filter function with multiple filters

I would like to build a search function with several different filters. I have a RangeSlider component and function that give me the respective min max values. I save these filter values as objects and send them to the backend immediately each time a filter is changed.
Here I work with if, else conditions, which is certainly not the right way, but I didn't know what else to do and wanted to have at least a working prototype.
If you have one or two filters, this can still work, but not if you have many different ones. Furthermore, I wonder how to optimise the whole filtering process? With every request, the entire collection is searched. It would be great if the previous search query is applied to each new filter instead of searching through the entire collection again.
How can this be achieved?
Frontend
Every time a filter is updated activeFilters will be sent to the backend
const activeFilters = reactive({ salePrice: '', space: '' })
async function updateFilter(minmax, property) {
activeFilters[property] = minmax
const filteredObjects = await $fetch('/api/properties/filtered', {
method: 'POST',
body: activeFilters,
})
return filteredObjects
}
Backend
body = { "salePrice": { "min": 630000, "max": 850948 }, "space": { "min": 53, "max": 167 } }
export default defineEventHandler(async (event) => {
const body = await readBody(event)
try {
if (body.salePrice !== '' && body.space !== '') {
const properties = await Property.find({
salePrice: { $gte: body.salePrice.min, $lte: body.salePrice.max },
livableSurface: { $gte: body.space.min, $lte: body.space.max },
})
return properties
}
if (body.salePrice !== '') {
const properties = await Property.find({
salePrice: { $gte: body.salePrice.min, $lte: body.salePrice.max },
})
return properties
}
if (body.space !== '') {
const properties = await Property.find({
livableSurface: { $gte: body.space.min, $lte: body.space.max },
})
return properties
}
const properties = await Property.find()
return properties
} catch (err) {
console.dir(err)
event.res.statusCode = 500
return {
code: 'ERROR',
message: 'Something went wrong.',
}
}
})
Html
<InputsRangeSlider
:config="salePriceSliderConfig"
#updated-min-max="updateFilter($event, 'salePrice')"
/>
<InputsRangeSlider
:config="spaceSliderConfig"
#updated-min-max="updateFilter($event, 'space')"
/>
Maybe something like this?
const {salePrice, space} = body;
const conditions = {};
if (salePrice) conditions.salePrice = {$gte: salePrice.min, $lte: salePrice.max};
if (space) conditions.livableSurface = {$gte: space.min, $lte: space.max};
return Property.find(conditions);

Filter only the latest data for the same ID in an object, using timestamp in Angular 6

I have an array of objects stored in 'component' variable
component=[{id:1,date:'20-10-2020'},{id:1,date:'13-01-2020'},{id:2,date:'30-03-2020'}]
Here I'm having 2 objects with 'id' as same(id:1) but with different dates. If there are multiple objects with the same id in it, I need to take out only the id with the latest date. Is it possible with filters?
After filtering, I need the output like
component=[{id:1,date:'20-10-2020'},{id:2,date:'30-03-2020'}]
Here '{id:1,date:'13-01-2020'}' is removed from the array.
Thanks in advance
You may do so using the following code which makes use of a Map:
let map = new Map();
component.forEach(e => {
if (map.get(e.id) !== undefined) {
// current date
const [newDay, newMonth, newYear] = e.date.split("-")
let newDate = new Date(newYear, newMonth - 1, newDay);
// previous date
const [oldDay, oldMonth, oldYear] = map.get(e.id).split("-")
let oldDate = new Date(oldYear, oldMonth - 1, oldDay);
// compare the date and pick the latest
map.set(e.id, newDate > oldDate ? e.date : map.get(e.id));
} else {
map.set(e.id, e.date);
}
});
// clear the original contents
component = [];
// now populate it from the map
for (let e of map.entries()) {
component.push({id: e[0], date: e[1]});
}
console.log(component);
Try the following example please
I must move soon, if I am well I will comment on what I did
const data = [
{ id: 1, date: "20-10-2020" },
{ id: 1, date: "13-01-2020" },
{ id: 2, date: "30-03-2020" },
];
const output = data.reduce((previousValue, currentValue) => {
const entity = previousValue.find((entry) => entry.id === currentValue.id);
if (entity !== undefined) {
const [
currentValueDate,
currentValueMonth,
currentValueYear,
] = currentValue.date.split("-");
const [entityDate, entityMonth, entityYear] = entity.date.split("-");
const currentValueTimestamp = new Date(
currentValueYear,
currentValueMonth - 1,
currentValueDate
).getTime();
const entityTimestamp = new Date(
entityYear,
entityMonth - 1,
entityDate
).getTime();
const index = previousValue.findIndex(
(entry) => entry.id === currentValue.id
);
if (entityTimestamp > currentValueTimestamp) {
previousValue[index] = entity;
return previousValue;
}
}
return [...previousValue, currentValue];
}, []);
console.log(output);
See
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://stackoverflow.com/a/7151607/615274 Help me solve invalid date problem
/**
* Notice that I changed your date input format,
* because they are invalid as far as javascript Date object is concerned,
* or you can use momentJS.
*
* If you decide to use moment, then you could just do something like this
*
* moment('your date string goes here').format('DD-MM-YYYY')
*
* More information on date manipulation with moment can be found on their
* official website.
*
* */
let component=[{id:1,date:'10-20-2020'},{id:1,date:'01-13-2020'},{id:2,date:'03-30-2020'}]
function deDup(listOfObjects: Array<{id: number, [propName: string]: any}>): Array<{id: number, [propName: string]: any}> {
let res: Array<any> = [],
groupings: {[propName: number]: Array<any>} = {}; /**propName here will be the attribute of unique identifier, eg id */
/**First group the similar objects under the same id */
listOfObjects.forEach(object => {
if (!groupings[object.id]) groupings[object.id] = [];
groupings[object.id].push(object)
})
/**Next order the duplicates based on the date attribute */
for (let key in groupings) {
let groupingItems = groupings[key].sort((a: any, b: any) => {
return new Date(a.date) > new Date(b.date) ? 1 : 0
});
/**Now, from each grouping, pick the first one, as it is the latest, based on the sorting */
res.push(groupingItems[0]);
}
return res;
}
let res = deDup(component);
console.log('res', res)
const component = [{
id: 1,
date: '20-10-2020'
}, {
id: 1,
date: '13-01-2020'
}, {
id: 2,
date: '30-03-2020'
}];
const byLatestDate = input => {
const parse = date => {
const [day, month, year] = date.split("-");
return new Date(year, month, day);
};
return component.filter(({id,date}) =>id === input.id && date !== input.date)
.every(({date}) => parse(date) < parse(input.date));
}
console.log(component.filter(byLatestDate));
Hope it works for you.

value.getTime is not a function GraphQL custom scalar Date

I receive LASTUPDATE: 1579452599 response from an external API,
I want to parse the value in this format: Mon Jan 19 2020 13:44:04, I tried using custom scallar, but I'm having this error:
value.getTime is not a function
What am I doing wrong?
This is my code,
resolvers.js
import fetch from 'node-fetch';
import { GraphQLScalarType } from 'graphql';
import { Kind } from 'graphql/language';
export const resolvers = {
Query: {
getCrypto: async() => {
const response = await fetch('https://min-api.cryptocompare.com/data/top/totalvolfull?limit=10&tsym=USD&api_key=260d15e639be7b967c2b0e4f9f3b6d656897ccbdfe772b1d24818d9f96d3a6ed')
let data = await response.json()
return data.Data[0].RAW.USD;
}
},
Date: new GraphQLScalarType({
name: 'Date',
description: 'Date custom scalar type',
parseValue(value) {
return new Date(value); // value from the client
},
serialize(value) {
console.log(value)
return value.getTime(); // value sent to the client
},
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return parseInt(ast.value, 10); // ast value is always in string format
}
return null;
},
})
};
schema.graphql
type CryptoCurrency {
FROMSYMBOL: String
PRICE: Float
TOSYMBOL: String
LASTUPDATE: Date
}
type Query {
getCrypto: CryptoCurrency
}
scalar Date
type MyType {
created: Date
}
In console I see the value
In case anyone else comes here from a google search for a similar issue
You should convert LASTUPDATE from timestamp to actual date, and have to multiply by 1000 because Javascript uses milliseconds.
serialize(value) {
console.log( new Date(value).toISOString())
return new Date(value * 1000).toISOString(); // value sent to the client
}

property missing in returned json response / javascript

Im working in React on some weather widget which displays temp and rain forecast. Im fetching data from OpenWeather and my json response looks like:
//rainy day
0:{
main: {
temp:10}
rain: {
3h: 1000}
}
//sunny day
1:{
main: {
temp:10}
}
the problem is rain.3h property appears in returned response only when it has some data, otherwise its missing. My request looks like:
async getForecast(term) {
const forecastUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + term + "&appid=" + apiKey + "&lang=us&units=metric&cnt=16";
try {
let response = await fetch(forecastUrl);
if (response.ok) {
let jsonResponse = await response.json();
let forecast = jsonResponse.list.map(
day => {
return {
temp: day.main.temp,
rain: day.rain["3h"], // can't map missed property
}
}
)
return (forecast);
}
} catch (error) {
console.log(error);
}
}
And Im getting error
TypeError: Cannot read property '3h' of undefined.
How may I add default rain:0 when the property is missing from response
You could do a check using ternary operator
let forecast = jsonResponse.list.map(
day => {
return {
temp: day.main.temp,
rain: day.rain?day.rain["3h"] : ''
}
}
)
You should check whether the property exists or not
var obj = {};
obj.temp = day.main.temp;
if (day.hasOwnProperty("rain") && day.rain.hasOwnProperty("3h"))
obj.rain = day.rain["3h"];
return obj;
You can use assignment with double ampersand "&&":
let forecast = jsonResponse.list.map(
day => {
return {
temp: day.main.temp,
rain: day.rain && day.rain["3h"] || 0
}
}
)
This works because if day.rain is undefined then the second part of the boolean expression will not be evaluated, avoiding the cannot read property of undefined error, and the value from the OR will be used for default assignment.

node red function and export to CSV

I have the raspberry pi and sense hat. I wish to extract acceleration z,y,x,Temperature and Pressure and time to csv. However, the code I've written does not do what i want it to do. I was expecting the data to leave the function in an array but the debug window shows them as separate objects. How do i get acceleration z,y,x and time to leave as one array so i can export to CSV?
29/03/2017, 17:17:23node: abf1ef08.31a6f
msg : Object
object
payload: 0.9487
_msgid: "ae0db049.020f6"
29/03/2017, 17:17:23node: abf1ef08.31a6f
msg : Object
object
payload: 0.2781
_msgid: "ae0db049.020f6"
29/03/2017, 17:17:23node: abf1ef08.31a6f
msg : Object
object
payload: 0.1491
_msgid: "ae0db049.020f6"
29/03/2017, 17:17:23node: abf1ef08.31a6f
msg : Date
"Wed Mar 29 2017 16:17:25 GMT+0000 (UTC)
Here's the function code :
var msgAccelZ,msgAccelX,msgAccelY,msgTemperature,msgPressure,msgCurrentTime;
if (msg.topic === 'motion') {
msgAccelZ = { payload: msg.payload.acceleration.z, };
msgAccelX = { payload: msg.payload.acceleration.x, };
msgAccelY = { payload: msg.payload.acceleration.y, };
} else if (msg.topic === 'environment') {
msgTemperature = { payload: msg.payload.temperature };
msgPressure = { payload: msg.payload.pressure };
}
msgCurrentTime = new Date();
return [ [msgAccelZ, msgAccelX, msgAccelY,msgCurrentTime] ,[msgTemperature, msgPressure, msgCurrentTime] ];
A Function needs to return a message object, not just a raw value.
By convention, you'd put the data you want to return under msg.payload:
msg.payload = [ [msgAccelZ, msgAccelX, msgAccelY,msgCurrentTime] ,[msgTemperature, msgPressure, msgCurrentTime] ];
return msg;
The documentation for the Function node explains in more detail: http://nodered.org/docs/writing-functions

Categories