How to use sortBy using react datepicker and lodash - lodash

I want to sort my events based on the dates the user gives them. I am using react datepicker and Lodash to sort the events desc.
My code React JS
const events = _.sortBy(this.props.events, [["seconds"]])
console.log(JSON.stringify(events))
Output console.log
[
{"date":{"seconds":416617200,"nanoseconds":0},,"title":"Past event 1983"},
{"date":{"seconds":1995231600,"nanoseconds":0},"title":"Future event 2033"},
{"date":{"seconds":1585090800,"nanoseconds":0},"title":"Present event 2020"},
{date":{"seconds":1677625200,"nanoseconds":0},"title":"Future event 2023"}
]
When I am trying orderBy "date" I also don't get the desired result
const events = _orderBy(this.props.events, "date")
console.log(JSON.stringify(events))
console.log:
[
{"date":{"seconds":1995231600,"nanoseconds":0},"title":"Future event 2033"},
{"date":{"seconds":1585090800,"nanoseconds":0},"title":"Present event 2020"},
{date":{"seconds":1677625200,"nanoseconds":0},"title":"Future event 2023"}
{"date":{"seconds":416617200,"nanoseconds":0},,"title":"Past event 1983"},
]
As you can see the seconds are not orderBy correctly in both cases.
Please advise how to use orderBy with Lodash when using React Date Picker?
Many thanks

Related

How to determine mouse events in React Native (mobile)?

I need to use a callback function for the mouse click event. Below code is working in React web app:
const checkAnswer = (e: React.MouseEvent<HTMLButtonElement>) => {
const answer = e.currentTarget.value // here .value property is undefined and gives error in React-Native. Just e.currentTarget is defined.
const correct = questions[number].correct_answer === answer
if(correct) setScore(prev => prev + 1)
}
But I couldn't apply it on React Native (mobile) for Pressable or TouchableOpacity.
This is the render part of React web app's code:
<button value={answer} onClick{checkAnswer} />
and I try to apply it on React Native. The value will be passed to button's value. But there is no "value" option in native's Pressable component. Therefore I am confused
Any help?
you can determine touch events by following
<View onTouchStart={(e) => {console.log('touchMove',e.nativeEvent)}} />
Here is some similar scenario what I could able to understand from the question.
There is a Score state which will store the user's score of a quiz game.
There is a array of question where all the options and correct option are given.
There will be a button for the option, if user choose a option, and based on that it will validate if user is correct or not.
It might not be the exact scenario of you. But this could definitely help to solve your scenario.
Here is a solution for the scenario => solution.
If you click on the solution link you will be redirect to a page which is similar to the screenshot attached below. On very right you will find "My Device", "Android", "ios", choose any and run. Run via "my device" with expo app installed in your mobile if you don't want to be in queue for some certain time.
Note: from your code this is for React web:
<button value={answer} onClick{checkAnswer} />
but in React Native you have to use a click event like this:
<TouchableOpacity onPress={()=>buttonHandler()}></TouchableOpacity>
Here ()=> and () extra need to be added to work a function properly.
Also instead of .map() function you can use FlatList to improve your app. FlatList support lazy loading.

allowed-dates attribute in Vuetify date picker is not responsive

I have a web page that displays a Vuetify date-picker component.
When the page is loaded or when the month is changed, I make an AJAX call that runs an SQL query to return the dates in that specific month when a particular event occurred.
Then, I only want to make these specific dates clickable.
As per the Vuetify documentation, the allowed-dates attribute allows you to do this.
After some experimentation, I have come across some unexpected difficulty:
The allowed-dates attribute takes in a function instead of, for example, an array. So, I had to create a function that will consult an "allowed dates" array that is returned by my AJAX call
Furthermore, the function is called when the date-picker is rendered and NOT when the AJAX call returns, so I end up with no dates being activated or only one date being activated on only the last date of the month being activated.
Am I missing something? is the allowed-dates attribute not responsive? I would prefer to stick with Vuetify since I am using it for the rest of the UI, but I am willing to switch to something else if a solution cannot be found.
There's some confution when an example in docs says:
You can specify allowed dates using arrays, objects, and functions.
But in API allowed-dates consumes only functions.
I guess the answer is to correctly define allowedDates function.
You first need to create an empty reactive array, then assign data into it via AJAX call, and in allowedDates function you just be able to compare the displayed page of dates with the dates in the array.
So the code is...
<v-date-picker
v-model="date"
:allowed-dates="allowedDates"
/>
...
data: () => ({
date: '2022-01-11',
allowedDatesArray: [],
}),
mounted() {
this.getAllowedDates();
},
methods: {
allowedDates(val) {
return this.allowedDatesArray.includes(val);
},
async getAllowedDates() {
this.allowedDatesArray = [];
await //...your AJAX call that must assign allowedDatesArray
}
}
I created a sandbox at CodePen where you may test this solution with some static dates that loading asynchronously using Promise.
In your solution you need to replace Promise with your AJAX call.

Vue countdown timer prints out on console.log but don't get passed on as data

I am using moment js to countdown the time as 10,9,8,7,6 . It successfully counts down time on console.log but I am not able to pass that as a data.
Below is my code on jsfiddle
https://jsfiddle.net/ujjumaki/817bqn52/9/
Change the function inside setInterval to an arrow functions, in order to read this as the Vue component:
setInterval(() => {
duration.subtract(interval, "milliseconds"); //using momentjs substract function
this.countdownTimer = moment(duration.asMilliseconds()).format('s');
console.log(moment(duration.asMilliseconds()).format('s'));
/* countdown timer works for console.log */
}, interval );
This is because this in the setInterval handler by default points to the window object. You could change this by adding .bind(this) to the function, or using an arrow function. Update JSFiddle: https://jsfiddle.net/qg4863tv
Read more about this here: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval#The_this_problem

Vue broadcast event to multiple components

I have a fairly simple component based question.
If I had 5 components and I click open on one, how can I tell the other 4 that they need to be closed?
To begin with I have put
this.$emit('open');
on the component. Then on the app I have put
#open="closeOthers"
Then in the app I have the following:
'methods':{
closeOthers : function($event){
console.log($event);
}
}
But I'm just logging undefined. How can I
make this not log undefined
update the props on all other components
Full code and demo here >>>
for 1st. You should pass event throw functions. Like this
'toggleSelect' : function(e){
this.$emit('open', e);
this.question.open = !this.question.open;
},
after this. This code will work
'methods':{
closeOthers : function($event){
console.log($event);
}
}
for 2nd. To control open state it is better to move open value to parent and pass it to child.
Full code jsfiddle

ReactTestUtils.Simulate can't trigger event bind by addEventListener?

Here is the example:
http://jsfiddle.net/hulufei/twr4thuh/7/
It just worked when bind onClick in virtual dom(like line 18), but If I comment line 18 and comment off line 8 to bind click with addEventListener, it failed.
So what's the problem?
TestUtils triggers events within react's synthetic event system, so the native event that addEventListener listens for is never going to be triggered. You will need to use the native click method on the element in your test:
var events = Events();
ReactTestUtils.renderIntoDocument(events);
events.refs.button.getDOMNode().click();
events.state.event.should.equal('click');
Additionally, you've misspelled clickHandler in your addEventListener definition.
jsfiddle
You can also simplify adding your event listener by reusing your prop definition:
componentDidMount: function () {
this.refs.button.getDOMNode().addEventListener('click', this.clickHandler);
},
Note:
Is there a reason why you want to use addEventListener instead of just passing an onClick attribute for your button? Unless there's a specific and good reason otherwise, i'd suggest doing things the react way when handling events for sanity :)
Edit
I originally mentioned that I did not know what TestUtils' SimulateNative.click did not trigger the event. I was wrong in thinking that it ever would since it would be simulating a native click event within the react even system. #thilo pointed me in the right direction :)
I had many problems while testing addEventListener, and I got the following conclusion.
You can create the events listener with pure javascript, jquery, but when running the tests with Jest I always had a problem.
The rendering of ReactTestUtils does not work directly with the document, and when we do:
For example, our events were added in the document, when rendering with ReactTestUtils it creates a div and renders it in the div, This way I could not get Simulate to trigger the call.
My first solution was to use jquery to create the listener and to test I did the render manually by appending the div in document.body, and triggered the events with the dispachEvent of javascript. But I thought the code was dirty, not the best way to work.
I made a sample code by adding the event and testing it with Jest, also have a test teaching to get all the listener that were created.
You can find the code here: https://github.com/LVCarnevalli/create-react-app/tree/master/src/components/datepicker
Component:
componentDidMount() {
ReactDOM.findDOMNode(this.datePicker.refs.input).addEventListener("change", (event) => {
const value = event.target.value;
this.handleChange(Moment(value).toISOString(), value);
});
}
Test:
it('change empty value date picker', () => {
const app = ReactTestUtils.renderIntoDocument(<Datepicker />);
const datePicker = ReactDOM.findDOMNode(app.datePicker.refs.input);
const value = "";
const event = new Event("change");
datePicker.value = value;
datePicker.dispatchEvent(event);
expect(app.state.formattedValue).toEqual(value);
});
Links:
window.addEventListener not triggered by simulated events: https://github.com/airbnb/enzyme/issues/426
Creating and triggering events: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events