getTime() method behaves differently in js - javascript

I have an array of object like :
[
{
"order_id": 1,
"customer": "Karita Klimochkin",
"country": "Sweden",
"address": "8978 Westridge Park",
"product_title": "Yellow-bellied marmot",
"product_description": "Bread - Flat Bread",
"date": "21/08/2020",
"status": "Delivered"
},
{
"order_id": 2,
"customer": "Ferne Roman",
"country": "China",
"address": "1370 Ridge Oak Pass",
"product_title": "Two-toed sloth",
"product_description": "Asparagus - White, Fresh",
"date": "24/07/2020",
"status": "Completed"
}
]
I want to sort objects by date. so when I use getTime() method it gives me different result.
orders.map(order => new Date(order.date).getTime())
results are :
1628100000000
NaN
What is the problem here?

You need to convert the date to mm/dd/yyyy format from dd/mm/yyyy so that JS can understand it properly
orders.map(order => {
const parts= order.date.split("/")
return new Date(`${parts[1]}/${parts[0]}/${parts[2]}`).getTime()
})

You cannot count on the default date parser to parse your DD/MM/YYYY format correctly. Parsing date strings through the constructor in this way is highly discouraged because it is implementation-dependent. Different browsers/runtimes will parse dates differently.
Instead, manually parse the date yourself and then construct the date object:
orders.map(order => {
const [d, m, y] = order.date.split('/');
return +new Date(+y, m-1, +d);
})

Friendly reminder: do you have a sorting functionality yet? .map is just an iteration through your array.
More about map: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Add a sort function based on your date(properly parsed) property and return a new array would help.

The dates are in the wrong format:
// from: "21/08/2020"
let format = obj.date.split('/').reverse().join('-')
// to: "2020-08-21"
In order to be sortable, dates must be in ms since Jan 1, 1970. Assign the new value to a new key:
obj.pDate = Date.parse(format);
Sort by the new key/value:
let results = orders.sort((a, b) => a.pDate = b.pDate)
Then remove all of the new key/values:
results.map(order => delete order.pDate)
const data = [{
"order_id": 1,
"customer": "Karita Klimochkin",
"country": "Sweden",
"address": "8978 Westridge Park",
"product_title": "Yellow-bellied marmot",
"product_description": "Bread - Flat Bread",
"date": "21/08/2020",
"status": "Delivered"
},
{
"order_id": 2,
"customer": "Ferne Roman",
"country": "China",
"address": "1370 Ridge Oak Pass",
"product_title": "Two-toed sloth",
"product_description": "Asparagus - White, Fresh",
"date": "24/07/2020",
"status": "Completed"
}, {
"order_id": 3,
"customer": "zer00ne",
"country": "US",
"address": "123 Main St",
"product_title": "Jackalope",
"product_description": "Chili Cheese Fries",
"date": "12/05/2020",
"status": "Delivered"
},
];
const sortOrders = orders => {
let result = orders.sort((a, b) => {
a.pDate = Date.parse(a.date.split('/').reverse().join('-'));
b.pDate = Date.parse(b.date.split('/').reverse().join('-'));
return a.pDate - b.pDate;
})
result.map(order => delete order.pDate);
return result;
};
console.log(sortOrders(data));

Related

Javascript: stuck with comparison function

I am stuck and need help finishing this fetch request.
I need a function to check if the movie (a single object) in the request has previously been rated by the user.
The ratings are in the ratedMovies array. If the movie was rated I need the userRating property with it's value to be added to the response. If it has not been rated, I need the userRating value to be null
const ratedMovies = useStore((state) => state.ratedMovies)
const getMovieDetails = () => {
const key = `https://www.omdbapi.com/?i=${movie.imdbID}&apikey=b46dc190`
axios
.get(key)
.then((response) => {
// Here a comparison is required, to check if the movie in the response (a single object)
// has ever been rated before and its ID (imdbID) and userRating (property to be added) is
// present in the ratedMovies array
// if it is present I need the property userRating nad it's value to be added to the response
// or when it is empty, to have the userRating be null
setModalDetails(response.data)
})
.then((response) => {
console.log(modalDetails)
})
.catch((error) => console.log(error))
}
Sample axios response:
{
"Title": "Star Wars: Episode V - The Empire Strikes Back",
"Year": "1980",
"Rated": "PG",
"Released": "20 Jun 1980",
"Runtime": "124 min",
"Genre": "Action, Adventure, Fantasy",
"Director": "Irvin Kershner",
"Writer": "Leigh Brackett, Lawrence Kasdan, George Lucas",
"Actors": "Mark Hamill, Harrison Ford, Carrie Fisher",
"Plot": "After the Rebels are brutally overpowered by the Empire on the ice planet Hoth, Luke Skywalker begins Jedi training with Yoda, while his friends are pursued across the galaxy by Darth Vader and bounty hunter Boba Fett.",
"Language": "English",
"Country": "United States, United Kingdom",
"Awards": "Won 2 Oscars. 25 wins & 20 nominations total",
"Poster": "https://m.media-amazon.com/images/M/MV5BYmU1NDRjNDgtMzhiMi00NjZmLTg5NGItZDNiZjU5NTU4OTE0XkEyXkFqcGdeQXVyNzkwMjQ5NzM#._V1_SX300.jpg",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "8.7/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "94%"
},
{
"Source": "Metacritic",
"Value": "82/100"
}
],
"Metascore": "82",
"imdbRating": "8.7",
"imdbVotes": "1,209,128",
"imdbID": "tt0080684",
"Type": "movie",
"DVD": "21 Sep 2004",
"BoxOffice": "$292,753,960",
"Production": "N/A",
"Website": "N/A",
"Response": "True"
}
Sample rating:
ratedMovies = [{imdbID: 'tt0080684', userRating: 8}]
Ok if I understand it correctly it goes like this:
let data = response.data;
let newMovieId = data.imdbID;
ratedMovies.forEach((movie) => {
if(movie.imdbID === newMovieId) {
data.userRating = movie.userRating;
}
});
setModalDetails(data)
code above goes inside the axios success callback
You can use .filter function like this:
ratedMovies = [{imdbID: 'tt0080684', userRating: 8}]
notratedMovies = [{imdbID: 'tt0080111', userRating: 8}]
let result = ratedMovies.filter(obj => {
return obj.imdbID === imdb.imdbID
});
console.log(result);
let notresult = notratedMovies.filter(obj => {
return obj.imdbID === imdb.imdbID
});
console.log(notresult);

Destructuring a json object in Javascript

How would access the _id and state values?
Here's the data
{
"data": {
"totalSamplesTested": "578841",
"totalConfirmedCases": 61307,
"totalActiveCases": 3627,
"discharged": 56557,
"death": 1123,
"states": [
{
"state": "Lagos",
"_id": "O3F8Nr2qg",
"confirmedCases": 20555,
"casesOnAdmission": 934,
"discharged": 19414,
"death": 207
},
{
"state": "FCT",
"_id": "QFlGp4md3y",
"confirmedCases": 5910,
"casesOnAdmission": 542,
"discharged": 5289,
"death": 79
}
]
}
}
What you have shown is a string in JSON format. You can convert that to a JavaScript object and then start to get the values you need from it.
let str = ‘{
"data": {
"totalSamplesTested": "578841",
"totalConfirmedCases": 61307,
"totalActiveCases": 3627,
"discharged": 56557,
"death": 1123,
"states": [
{
"state": "Lagos",
"_id": "O3F8Nr2qg",
"confirmedCases": 20555,
"casesOnAdmission": 934,
"discharged": 19414,
"death": 207
},
{
"state": "FCT",
"_id": "QFlGp4md3y",
"confirmedCases": 5910,
"casesOnAdmission": 542,
"discharged": 5289,
"death": 79
}
]
}
} ‘;
(Note, I have put the string in single quotes so it can be shown properly here but in your code you need to put it in back ticks so it can span many lines)
Now convert it to a JavaScript object.
let obj = JSON.parse(str);
Now look closely at the string to see how the object is structured. It actually has just one item in it, data. And that is itself an object with several items, one of which is states which is an array.
So, obj.data.states[0] is the array’s first entry. That is an object and has _id and state items.
You can step through the array extracting the ._id and .state entries.

how to get particular Keys Values from the exiting JSON Object in javacsript? [duplicate]

This question already has answers here:
How to get a subset of a javascript object's properties
(36 answers)
Closed 3 years ago.
I have one JSON Object and I want to create subset of JSON with particular keys values.
JSON Object
{
"Checksum": "OK",
"ID": "012B4567",
"DOB: "12-12-1991"
"Data": "Test Line 1 >>>>>↵Test Line 2 >>>>>↵Test Line 3 >>>>>",
"issue: "11-April-2015",
"DocID": "PASSPORT",
"Number: "123456789",
"Document": "PASSPORT",
"Photo": "Qk06AAAAAAAAA",
"ExpiredFlag": false,
"ExpiryDate": "01 Apr 12",
"Forename": "IMA Phoney",
"Image2": "/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ",
"ImageSource1": 0,
"Image3": "/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ",
"Image1": "/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ",
"IssueState: "USA",
"Nationality": "USA",
"PlaceOfBirth": "U.S.A",
"SecondName": "J",
"Sex": "Male",
"Surname": "XYZ"
}
I want subset from above like below:
{
"ID": "012B4567",
"Number: "123456789",
"Document": "PASSPORT",
"IssueState: "USA",
"Nationality": "USA",
"PlaceOfBirth": "U.S.A",
"SecondName": "J",
"Sex": "Male",
"Surname": "XYZ"
}
I have tried below code. It is working fine, But I am not able to understand. I need simplest way:
var data={
"CDRValidation": "CDR Validation test passed",
"AirBaudRate": "424",
"ChipID": "012B4567",
"BACStatus": "TS_SUCCESS",
"SACStatus": "TS_NOT_PERFORMED",
"Data": "Test Line 1 >>>>>\nTest Line 2 >>>>>\nTest Line 3 >>>>>",
"DocType": "PASSPORT",
"DocNumber": "123456789",
"DocID": "PASSPORT",
"Surname": "Person",
"Forename": "IMA Phoney",
"SecondName": "J",
"Nationality" : "Imaging Automation Demo State",
"Sex": "Male",
"DOB": "12 May 70",
"ExpiryDate": "01 Apr 12",
"IssueState": "Passport Agency Billerica",
"ExpiredFlag": false,
"ImageSource": 0,
"OptionalData1": "123456789123456",
"OptionalData2": "",
"DateOfIssue":"11 April 02",
"PlaceOfBirth":"Illinois, U.S.A"
}
console.log("----------------->",data);
var Fields = ({
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
} = data, {
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
})
console.log("--------subset--------->",Fields);
There are multiple ways you can handle this case. Object destructuring as you have done in your example is one simple way. You can also use an array to store the required keys and write code as below
function subset(parentObj) {
const keys = ['key1', 'key2', 'key3'];
const obj = {};
for (let i = 0, length = keys.length; i < length; i += 1) {
obj[keys[i]] = parentObj[keys[i]];
}
return obj;
}
Or you can also use the above code with some functional programming
function subset(parentObj) {
const keys = ['key1', 'key2', 'key3'];
return keys.reduce((acc, key) => ({
...acc,
[key]: parentObj[key];
}), {});
}
A simple to achieve what you are asking using ES5 is to create a list of all the properties you want to keep, and using Array#reduce add each property to a new object.
// Saves vertical space for example
var original = JSON.parse(`{"Checksum":"OK","ID":"012B4567","DOB":"12-12-1991","Data":"Test Line 1 >>>>>↵Test Line 2 >>>>>↵Test Line 3 >>>>>","issue":"11-April-2015","DocID":"PASSPORT","Number":"123456789","Document":"PASSPORT","Photo":"Qk06AAAAAAAAA","ExpiredFlag":false,"ExpiryDate":"01 Apr 12","Forename":"IMA Phoney","Image2":"/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ","ImageSource1":0,"Image3":"/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ","Image1":"/9j/4AAQSkZJRgABAQEBkAGQAAD/2wBDAAgGBgcGBQgHBwcJCQ","IssueState":"USA","Nationality":"USA","PlaceOfBirth":"U.S.A","SecondName":"J","Sex":"Male","Surname":"XYZ"}`);
var propertiesToUse = ["ID", "Number", "Document", "IssueState", "Nationality", "PlaceOfBirth", "SecondName", "Sex", "Surname"];
var result = propertiesToUse.reduce(function(result, key) {
return result[key] = original[key], result;
}, {});
console.log(result);
What you have done is a simple way, but if you are confused with it, you can divide it into two lines and explain it.
This line actually destrucutes your object and assign the value for the mentioned keys in the object to the corresponding variables.
{
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
} = data
Now, each of this variable has data individually, but we want it in an object. Therefore, we use the second part, i.e. creating an object with the following variable acting as keys.
{
IssueState,
ExpiryDate,
DateOfIssue,
PlaceOfBirth,
DOB,
Sex,
DocNumber,
DocType
}
When combined you get the desired result in a single statement.

for each does not work on object array when you filter

I m trying to get all the numbers from the list of all the contacts. Im probably not using forEach correctly any advice? I've put a sample of what is expected
//sample of a contact
Object {
"company": "Financial Services Inc.",
"contactType": "person",
"firstName": "Hank",
"id": "2E73EE73-C03F-4D5F-B1E8-44E85A70F170",
"imageAvailable": false,
"jobTitle": "Portfolio Manager",
"lastName": "Zakroff",
"middleName": "M.",
"name": "Hank M. Zakroff",
"phoneNumbers": Array [
Object {
"countryCode": "us",
"digits": "5557664823",
"id": "337A78CC-C90A-46AF-8D4B-6CC43251AD1A",
"label": "work",
"number": "(555) 766-4823",
},
Object {
"countryCode": "us",
"digits": "7075551854",
"id": "E998F7A3-CC3C-4CF1-BC21-A53682BC7C7A",
"label": "other",
"number": "(707) 555-1854",
},
],
},
//Expected
numbers = [
5557664823,
7075551854
]
//does not work
const numbers = contacts.map(contact => contact.phoneNumbers.forEach(number));
forEach always returns undefined, so your map callback returns undefined, so numbers will be full of undefineds.
I think you probably want to return the phone numbers (each number in the phoneNumbers array of each entry), and then perhaps flatten the result:
const numbers = contacts.map(contact => contact.phoneNumbers.map(({number}) => number)).flat();
Array.prototype.flat is relatively new, but easily polyfilled.
That's such a common pattern that there's a flatMap method to do it in one go:
const numbers = contacts.flatMap(contact => contact.phoneNumbers.map(({number}) => number));
Or just a simple loop with push:
const numbers = [];
for (const {phoneNumbers} of contacts) {
numbesr.push(...phoneNumbers.map(({number}) => number));
}
Probably want to use reduce and map
let numbers = contacts.reduce((p, c, i) => {
return p.concat(c.phoneNumbers.map(pn => pn.number));
}, []);
I don't know how many times I've done that. forEach doesn't return anything.
const numbers = contacts.reduce((n, c)=>(a.concat(contact.phoneNumbers)),[]);
or
const numbers = contacts.reduce((n, c)=>(a.concat(contact.phoneNumbers.map(pn=>pn.number)),[]);

Add only unique objects to an array in JavaScript

Let's say I start with this:
var shippingAddresses = [
{
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"zip": "22201",
"country": "US"
},
{
"firstname": "Dan",
"lastname": "Hess",
"address1": "304 Riversedge Dr",
"address2": "",
"city": "Saline",
"state": "MI",
"zip": "48176",
"country": "US"
}
]
I use this to prepopulate a form.
Users can edit entries or add new ones. I need to prevent them from adding duplicates.
The issue is that the structure of the form that I am serializing and the order these values are returned from the database are not the same, so there is a chance that I will insert an item into this array with the following format:
{
"country": "US",
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"zip": "22201",
"city": "Arlington",
"state": "VA"
}
Which is the same as the first entry, just ordered differently.
I am loading underscorejs, so if there's a way to handle it with that library that would be great. I'm also using jQuery if that helps.
At this point I'm not sure how to proceed.
The Underscore findWhere function does exactly what you need - it's not an indexOf search by object identity, but searches objects whose properties have the same values as the input.
if (_.findWhere(shippingAddresses, toBeInserted) == null) {
shippingAddresses.push(toBeInserted);
}
Basic example using lodash union method:
var a = [1,2,3];
// try to add "1" and "4" to the above Array
a = _.union(a, [1, 4]);
console.log(a);
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
While this doesn't directly answers the question, it does answers the broader question of how to add unique values to an Array, and like myself, others might stumble upon this page from google.
based on this answer to: "js-remove-an-array-element-by-index-in-javascript"
https://stackoverflow.com/a/7142909/886092
I'm using the following idiom that is concise and does not require underscore.js or any other framework.
Here is an example for recording selected and deselected rows for DataTables jquery plugin.
I keep an array of currently selected ids, and I don't want to end up with duplicates in the array:
in coffeescript
fnRowSelected: (nodes) ->
position = $selected.indexOf(nodes[0].id)
unless ~position
$selected.push nodes[0].id
return
fnRowDeselected: (nodes) ->
position = $selected.indexOf(nodes[0].id)
if ~position
$selected.splice(position, 1)
More generally it would
position = myArray.indexOf(myval)
unless ~position
myArray.push myVal
or in JS
var position;
position = myArray.indexOf(myval);
if (!~position) {
myArray.push(myVal);
}
If you want to check the user input object you could try this function:
var uniqueInput = {
"country": "UK",
"firstname": "Calvin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"zip": "22201"
};
var duplicatedInput = {
"country": "US",
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"zip": "22201"
};
var shippingAddresses = [{
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"zip": "22201",
"country": "US"
}, {
"firstname": "Dan",
"lastname": "Hess",
"address1": "304 Riversedge Dr",
"address2": "",
"city": "Saline",
"state": "MI",
"zip": "48176",
"country": "US"
}];
function checkDuplication(checkTarget,source){
_.each(source,function(obj){
if(_.isEqual(checkTarget,obj)){
alert("duplicated");
}
});
}
And try to invoke this check function in different parameter (uniqueInput and duplicatedInput)
I think it could check the duplication input in your shipping addresses.
checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);
I make a jsfiddle. You could try it.
Hope this is helpful for you.
EDIT, this will work with your example of unsorted properties:
var normalized_array = _.map(shippingAddresses, function(a){
var o = {};
_.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]});
return o;
})
var stringy_array = _.map(normalized_array, JSON.stringify);
shippingAddresses = _.map(_.uniq(stringy_array), JSON.parse});
and we could do this with a one-liner but it would be super ugly:
shippingAddresses_uniq = _.map(_.uniq(_.map(_.map(shippingAddresses, function(a){ var o = {}; _.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]}); return o; }), JSON.stringify)), JSON.parse});
I think you need this,
NOTE: No library is required.
let array = [{ id: 1}, {id: 2}, {id: 3}];
function addUniqeObj(data) {
let index = -1;
for(let i = 0, i < array.length; i++) {
if(array[i].id === data.id) {
index = i;
}
}
if(index > -1) {
array[index] = data;
} else {
array.push(data)
}
}
Basic example using Set() from ECMAScript 2015 (no library required)
The Set object lets you store unique values of any type (whether primitive values or object references). If an iterable object is passed, all of its elements will be added to the new Set. Here I'll just add one value:
// original array with duplicates already present
const numbers = [1, 1, 1, 2, 3, 100]
// Use Set to remove duplicate elements from the array
// and keep your new addition from causing a duplicate.
// New value (100) is not added since it exists (and array
// also is de-duped)
console.log(Array.from(new Set([...numbers, 100])))
// [1, 2, 3, 100]
// New, non-existing value (101) is added (and array is de-duped)
console.log(Array.from(new Set([...numbers, 101])))
// [1, 2, 3, 100, 101]

Categories

Resources