gotoDate() not working on FullCalendar in timeline view - fullcalendar

I'm using the timeline view of FullCalendar v5 and #fullcalendar/react and I want my clanedar to automatically to scroll to today. When I call .gotoDate() it doesn't do anything.
Here is my calendar code:
const calendarRef = useRef();
const getCalendarApi = () => {
const {current} = calendarRef;
return current?.getApi();
};
return (
<FullCalendar
ref={calendarRef}
timeZone="local"
initialView="resourceTimelineMonth"
...
/>
);
Here is the code I'm using to call gotoDate():
<button
type="button"
onClick={() => {
const calendarApi = getCalendarApi();
calendarApi.gotoDate(new Date());
}}
>
test
</button>
When I click the "test" button, nothing happens. I checked and calendarApi.gotoDate() is a valid function it's just not doing anything. Any ideas why this isn't working?
UPDATE #1:
I also tried adding initialDate="2021-03-23" to the <FullCalendar /> but it also doesn't do anything
UPDATE #2:
I tried adding validRange and it worked in that it scrolled to the start date but now it's not showing me any events before the start date.
return (
<FullCalendar
ref={calendarRef}
timeZone="local"
initialView="resourceTimelineMonth"
validRange={()=> {
return {
start: "2021-03-20",
end: "2021-03-31"
};
}}
...
/>
);

Related

Creating on/off button in react

I am making a button that is going to say "disable" when its on and "enable" when its off. how do I do that in react?? I have tried to make it but I have no idea where to even start, is there some syntax im missing?
The code below does the job of displaying the button text based on a state.
Inside the useState() hook you can specify the initial state.
On the button's click event the state will be reversed to toggle between true and false
const customButton = () => {
const [enabled, setEnabled] = useState(false);
return (
<button
onClick={() => setEnabled(!enabled)}>
{enabled ? "disable" : "enable"}
</button>
);
}

Why Material UI buttons not working correctly on onClick events? [duplicate]

I am trying to add an onClick eventhandler into a material ui and sometimes it is called, sometimes it is not. However, it's working fine with regular buttons
handleClick = (event) => {
const value = event.target.value;
console.log(value);
this.setState({ filtered: this.state.videos.filter(item => {
return item.category === value
})
})
<Button value="java" onClick={this.handleClick} color="primary">Java</Button>
<Button value="React" onClick={this.handleClick} color="primary">React</Button>
<Button value="C#" onClick={this.handleClick} color="primary">C#</Button>
<Button value="javascript" onClick={this.handleClick} color="primary">JavaScript</Button>
when I updated to console.log to get event.target, I got the result shown in the image below
I found the issue, but still don't know how yo fix it. React adds two spans to the Button that have no attribute name, so when I click the button, the function gets called, but not when I click the span
You can use event.currentTarget.value instead of event.target.value.
Material-ui's Button has a nested span inside the button, so when you use event.target.value and the user clicks the span you get the span as event.target, if you'd use event.currentTarget you'd get the element that the event listener is attached to - the button.
See a working example: https://codesandbox.io/s/cocky-cookies-s5moo?file=/src/App.js
Inside your handle click, you could also do:
return (item.category === value || item.category === event.target.innerHTML)
But obviously CD..’s answer is better
Besides relying on currentTarget, you can always curry the parameter to the callback function (imagine you are not passing in static content, but maybe the index of an iteration or some dynamic values stored in an object, etc)
Example
handleClick = (value) => () => {
console.log(value);
this.setState({ filtered: this.state.videos.filter(item => {
return item.category === value
})
})
<Button value="java" onClick={this.handleClick('java')} color="primary">Java</Button>
<Button value="React" onClick={this.handleClick('React')} color="primary">React</Button>
<Button value="C#" onClick={this.handleClick('C#')} color="primary">C#</Button>
<Button value="javascript" onClick={this.handleClick('javascript')} color="primary">JavaScript</Button>

react native navigate to a page with some parameter based on firebase dynamic link (probably just react native link should work the same way)

I am building an app with react native and I used firebase dynamic link to open the app. it works well but I want the user to navigate to a specific screen with some parameter I want to pass along when the app opens by responding to link.
Below is how my app.js looks like. this code is getting triggered every time I am clicking the link. now I want to navigate to some specific screen that will accept some parameters. e.g. navigation.navigate('Profile',{param1:'xyz', param2:'sdfds'}) but i am not sure how i can make it work. I could put this dynamic link handler in my initial route (Main screen as per below), but I tried it once and it did not quite work. I will try again but was wondering if there are some pointers?
import dynamicLinks from '#react-native-firebase/dynamic-links';
export default function App() {
const Stack = createStackNavigator();
const handleDynamicLink = link => {
dynamicLinks()
.getInitialLink()
.then(link => {
console.log(JSON.stringify(link) + 'i got triggered and app was open');
if (link.url === 'https://myapp.page.link/welcome') {
console.log('i got triggered and app was open');
//Stack.Navigator.initialRouteName = MenuScreen;
//navigation.navigate('Profile');
// ...set initial route as offers screen
}
});
// Handle dynamic link inside your own application
if (link.url === 'https://myapp.page.link/welcome') {
// ...navigate to your offers screen
console.log('i got triggered and app was closed');
//navigation.navigate('Profile');
}
};
useEffect(() => {
const unsubscribe = dynamicLinks().onLink(handleDynamicLink);
// When the is component unmounted, remove the listener
return () => unsubscribe();
}, []);
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: 'orange',
},
headerTintColor: 'black',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<Stack.Screen name="Menu" component={HomeScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Store" component={StoreScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

Next.js - How to make sure <title> is set by the time the history change event fires?

In my Next.js app, I'm setting the <title> tag for individual pages using the recommended method:
import Head from 'next/head'
export default () => <>
<Head><title>My page title</title></Head>
</>
Here's the problem: when the history change event fires, the value of document.title doesn't always match the current URL.
You can test it yourself:
Router.events.on("routeChangeComplete", () => {
if ('browser' in process) {
console.log('--------');
console.log(window.location.href);
console.log(document.title);
}
});
Navigating between pages, you should observe that URL & title are often mismatched. The value of URL is always right, but the value of title is all over the place. It can have:
the right value
the value it had on the previous page
no value at all
This is an issue when using analytics, specifically GTM - Google Tag Manager, which uses the current URL & page title to uniquely identify visited pages.
I've had this issue with Next.js 7, and upgrading to 8 hasn't fixed it.
Do you know of any way to solve this problem? Maybe delaying the history change event until the first render of a component under /pages/?
Thanks!
This is a small hack. setTimeout(()=>{console.log(document.title)}, 0)
I found a work-around by intercepting events sent to window.dataLayer.push and adding a one-second delay in case the event is gtm.historyChange.
Here's my GtagScript component that I'm adding to <Head> under _document.js:
export const GtagScript = () => {
function intercept() {
const scriptTag = document.querySelector('#gtm-js');
if (scriptTag !== null)
scriptTag.addEventListener('load', () => {
window.dataLayer.pushOrig = window.dataLayer.push;
window.dataLayer.push = (e) => {
if (e.event === 'gtm.historyChange') {
setTimeout(function () {
window.dataLayer.pushOrig(e);
console.log(`URL: ${window.location.href} Title: ${document.title}`);
}, 1000);
} else {
window.dataLayer.pushOrig(e);
}
};
});
}
return <>
<script
id="gtm-js"
async
src={`https://www.googletagmanager.com/gtm.js?id=${GA_TRACKING_ID}`}
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}');
${intercept.toString()}
intercept();`
}}
/>
</>
};
I'll wait a while to see if an official fix comes from the ZEIT team. My solution doesn't actually answer the question. It doesn't set <title>, it just defers the event, which isn't optimal.
You can use setInterval
const firstPageViewEvent = setInterval(() => {
if (document.title) {
// send pageview event
clearInterval(firstPageViewEvent);
}
}, 200);

Use setState to change the value of a grandchild object

Everything I have tried from what I can find doesn't seem to be working. I'm really curious how to access and edit grandchild objects located in the state with react. If anyone could tell me what I'm doing wrong, it would be very helpful.
https://codesandbox.io/s/0mo32q85pp
Take a look at the following code...
App.js
lines: 41-58
getHomeworld = URL => {
fetch(URL)
.then(res => {
return res.json();
})
.then(homeWorldObject => {
console.log(homeWorldObject);
// this.setState({ <- Why isn't this working????
// ...this.state.starwarsChars,
// ...this.state.nextPage,
// ...this.state.prevPage,
// ...this.state.starwarsChars.homeworld = homeWorldObject
// });
})
.catch(err => {
throw new Error(err);
});
};
lines: 86-89
<CharacterList
characters={this.state.starwarsChars}
getHomeworld={this.getHomeworld}
/>
CharacterList.js
lines: 8-12
<Character
key={character.name}
characterDetails={character}
getHomeworld={props.getHomeworld}
/>
Character.js
lines: 18-29
{Object.keys(props.characterDetails).includes("homeworld") ? (
<div className="character-homeworld">
<Homeworld
homeworld={props.getHomeworld(props.characterDetails.homeworld)}
/>
</div>
) : (
<div className="character-homeworld">
<h4>Homeworld</h4>
<p>None</p>
</div>
)}
Homeworld.js
lines: 7-10
<div className="homeworld-details">
<p>Name: {props.name}</p>
<p>Rotation Period: {props.rotation_period}</p>
</div>
Expected Output:
If you look on the sandbox webpage, the "Name" and "Rotation Period" (Under "Homeworld") should display the values from here: https://swapi.co/api/planets/1/
Is there anyone who can help me figure this out?
EDIT:
I got really close making these changes (using my local machine, the code on the sandbox is still the original)...
App.js
let temp = {...this.state.starwarsChars} // use spread operator to clone it, so you don't mutate state on next line;
for (let character in temp) {
if (temp[character].homeworld === URL) {
temp[character].homeworld = homeWorldObject;
}
}
// console.log(temp);
this.setState({
starwarsChars: temp
});
Character.js
const Character = props => {
props.getHomeworld(props.characterDetails.homeworld);
console.log(props.characterDetails); // returns object{homeworld: {object}}
console.log(props.characterDetails.homeworld); // returns url
and...
<div className="character-homeworld">
<Homeworld
homeworld={props.characterDetails.homeworld}/>
</div>
However, the issue now is if I do console.log(props.characterDetails.homeworld);, it logs homeworld: url
and...
if I do console.log(props.characterDetails);, it logs the property of the character object as homeworld: {object}
...
What I want is the 2nd one, and I'm not sure why it's not consistent.
Update
For some strange reason, codesandbox is console logging both urls, and when I run with yarn start, it logs the url for one, and the object for another. Because of this... I am adding the github link here -> https://github.com/jamespagedev/Sprint-Challenge-React-Wars (so the error can properly be reproduced)
Edit 2:
I changed the sandbox code to the following so we are now only worrying about the code in 1 file -> https://codesandbox.io/s/0mo32q85pp
Here is the issue I am now seeing, and I'm not sure how to solve it...
getHomeworld = URL => {
let home;
fetch(URL)
.then(res => res.json())
.then(homeWorldObject => {
home = homeWorldObject;
console.log(home); // home is an object
});
console.log(home); // why is home undefined?
return home;
};
I've tried doing return homeWorldObject, but the main function just returns undefined. After doing the console logging, that was what I found, and I'm not sure why that is happening...

Resources