server side rendering react Issue rendering a subroute - reactjs

I have a route: /events with a subroute /events/:id
I created a reducer and an action for fetching all the events and display them in the eventsPage.
This part works fine.
Now from the events page, when I click on an event I'm trying to navigate to /events/:id
In the events/:id page I created an action which is called in the componendDidMount callback then display the event from there.
It works fine when I click on a link to an event's details page from the list. Now I'm looking for the way to perform the request on the server side so when I do a full reload of the page, the selected event is still displayed.
Here is my events/:id page component
import React, { Component } from 'react';
import {connect} from 'react-redux';
import {fetchEvent} from '../actions/eventsActions'
class EventDetail extends Component {
constructor(props){
super(props);
this.state = {
event: null
}
}
componentDidMount(){
this.props.fetchEvent(this.props.match.params.slug).then(response => {
this.setState({
event: response.event
})
}).catch(error => {
console.log('error', error);
});
}
render() {
return (
<div>
{JSON.stringify(this.state)}
</div>
);
}
}
function loadData(store){
}
export default {
component: connect(null, {fetchEvent})(EventDetail),
loadData
};
my fetch_event action
import {FETCH_EVENT} from './types';
export const fetchEvent = (event_slug) => async(dispatch, getState, api) => {
const res = await api.get(`/api/events/${event_slug}`);
dispatch({
type: FETCH_EVENT,
payload: res.data
})
return res.data;
}
How can I fix this?

Related

How to access naviagtion options from imported file in react-native

I'm passing data through different pages down to the last page in my app, its been working fine.
But the issue is the last page has 2 components so the typical </ChatActivity navigation="{this.props.navigation}" />, here's what I mean:
I have an App.js
content of App.js
import ChatScreen from './chat'
class ChatActivity extends Component {
static navigationOptions = {
...
}
render() {
return(
<ChatScreen navigation={this.props.navigation} />
)
}
}
I also have chat.js that contains the chat component. Chat.js itself, needs to import Fire from './fire.js'
so now, this.props.navigation was only passed to Chat.js...but I need to access it from fire.js as well.
I've read about import {useNavigation}, but from what i have tried it didn't work cause my fire.js doesn't even look like the example in the docs
this is my fire.js
class Fire extends React.Component{
constructor (props) {
super(props)
this.init()
this.checkAuth()
}
init = () => {
firebase.initializeApp({
})
};
checkAuth = () => {
firebase.auth().onAuthStateChanged(user => {
if (!user) {
firebase.auth().signInAnonymously();
}
})
}
send = messages => {
messages.forEach(item => {
const message = {
text: item.text,
timestamp: firebase.database.ServerValue.TIMESTAMP,
// image: item.image,
//video: item.video,
user: item.user
}
this.db.child(`NEED NAVIGATION PARAMS HERE`).push(message)
})
}
parse = message => {
const {user, text, timestamp} = message.val();
const {key, _id} = message
const createdAt = new Date(timestamp)
return {
_id,
createdAt,
text,
user
}
}
get = callback => {
this.db.child(`NEED NAVIGATION PARAMS HERE`).on('child_added', snapshot => callback(this.parse(snapshot)))
}
off() {
this.db.off()
}
get db() {
return firebase.database().ref(`NEED NAVIGATION PARAMS HERE`);
}
get uid(){
return(firebase.auth().currentUser || {}).uid
}
}
export default new Fire();
Since i couldn't access navigation params, I tried AsyncStorage, but thats probably not the best practice and it isn't working too well. Not sure if its the AsyncStorage or react-native-gifted-chat but when I load the chat page once, it shows the same messages for other chats till I restart the app which shouldn't be cause i'm fetching the data based on unique parameters.
You have just missed one step here...
Since you have passed the navigation as props by using the following approach:
<ChatScreen navigation={this.props.navigation} />
the chat screen gets to use navigation properties of ChatActivity.
For Fire.js to be able to use the navigation as well, that was provided to Chat.js by ChatActivity you will need to pass the navigation props received by Chat.js to Fire.js in the same way.
This is how your Chat.js should look like:
import Fire from './Fire'
class Chat extends Component {
static navigationOptions = {
...
}
render() {
return(
<Fire navigation={this.props.navigation} />
)
}
}
That should solve the issue. Cheers!

React - what are the steps to get data from api and render it?

I am building a site just like stackoverflow.com. I want my home page to display top questions. For that, I have sample questions on the backed. Now, I want to display only the question and tags from the questions array.
The code is in the image
I have made axios connection for that:
const instance = axios.create({
baseURL: "https://2w2knta9ag.execute-api.ap-south-1.amazonaws.com/dev", });
instance.defaults.headers.post["Content-Type"] = "application/json";
To connect it, I wrote the command: instance.get("/questions)
Now, how do I display only the question and tags??
EDIT:
On using the code given bellow, my js file now becomes:
import React from 'react';
import instance from '../../api';
class QuestionList extends React {
componentDidMount() {
instance
.get("/questions")
.then((res) => {
this.setState({ data: res.data });
});
}
render () {
const { data } = this.state;
return <div>
{
data && data.map(d => {
return <div>question: {d.question}, tags: {d.tags}</div>;
})
}
</div>
}
}
export default QuestionList;
But, this is just making my site in a loading state, and it gets hanged!!
If I understood correctly, you want to get an array only with the tags and the question. if so, you can use Array.prototype.map for this
const questions = result.map(({ question, tags }) => ({ question, tags }))
First you export the axios instance so that it can be used from other components.
Now you can send the api request in componentDidMount and update your component's state with the data.
And in render function, you just get the value from state and display.
If you are new to react, learn React Hooks and know that componentDidMount method is the best place to send api requests.
For Example:
import React from 'react';
import instance from '../../api';
class QuestionList extends React.Component {
constructor() {
super();
this.state = {
data: [],
};
}
componentDidMount() {
instance.get('/questions').then((res) => {
this.setState({ data: res.data });
});
}
render() {
const { data } = this.state;
return (
<div>
{data &&
data.map((d) => {
return (
<div>
question: {d.question}, tags: {d.tags}
</div>
);
})}
</div>
);
}
}
export default QuestionList;

How do I pass browser properties to react app talking to MSBOT?

We have hosted a bot on ServiceNow and would now like to pass attributes from the browser to the BOT. How can I make this happen?
This question is actually part 2 of a question I had posted & which I have already found a solution for.
Since the BOT is already logged into ServiceNow. I want to extract some elements from the background/servicenow page source and pass it to the react app as shown below. The BOT authenticates the user by email so it would act like a SSO because he is already connected to ServiceNow with the same email id. We therefore want to simply pass that value.
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
setTimeout(() => {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'webchat/join',
value: {
language: window.navigator.language,
userid: "a.b#c.d",
username: "a.b#c.d"
}
}
});
}, 1000);
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
if (action.payload.activity.from.role === 'bot') {
this.setState(() => ({ newMessage: true }));
}
}
return next(action);
});
You can pass the data from your page to your bot by dispatching an event listener on the page and catching the event in the web chat implementation.
In this example, I am simulating a user having logged in with a button click. The button click creates the event. When the event is registered, it is picked up by web chat which then takes the values stored in window.NOW.user and forwards that data to the bot. To help drive the point home, I am sending a message greeting the user by name while also sending the data (name and email) behind the scenes.
Hope of help!
app.js: Imports the view for display.
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import WebChatView from './webChatView';
class App extends Component {
render() {
return (
<Router>
<div className="App">
<Route path="/" exact component={WebChatView} />
</div>
</Router>
);
}
}
export default App;
webChatView.js: I import the webchat component into the view and create a function that, on click (again, just to simulate someone having logged in), creates and dispatches an event.
import React, { Component } from 'react';
import WebChat from './webchat';
class WebChatView extends Component {
constructor(props) {
super(props);
this.sendToBot = this.sendToBot.bind(this);
}
render() {
return (
<div>
<div>
<WebChat id="webchat" role="main" />
</div>
<div>
<button id="loginBtn" onClick={this.sendToBot}>Login</button>
</div>
</div>
)
}
sendToBot = () => {
let sendToBotEvent = new Event('sendToBot')
window.dispatchEvent(sendToBotEvent);
window['NOW'] = {
'user': {
'name': 'John Doe',
'email': 'john.doe#somedomain.com'
}
}
}
}
export default WebChatView;
webchat.js: Lastly, is web chat, itself. I create a store and an event listener. When the event is dispatched in the window, the message/data is also dispatched to the bot. Because I'm simulating logging in as one step, I have included a setTimeout so the window.NOW.user data has a chance to save. The store is passed to <ReactWebChat> which, subsequently, sends the associated data to the bot for processing.
import React from 'react';
import ReactWebChat, { createDirectLine, createStore, } from 'botframework-webchat';
export default class WebChat extends React.Component {
constructor(props) {
super(props);
const store = window.WebChat.createStore();
window.addEventListener('sendToBot', () => {
setTimeout(() => {
store.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'Service Now user name',
value: window.NOW.user
}
})
store.dispatch({
type: 'WEB_CHAT/SEND_MESSAGE',
payload: {
text: `Hi ${window.NOW.user.name}!`
}
})
}, 300)
})
}
this.state = {
store: store
};
componentWilUnmount() {
window.removeEventListener('sendToBot', null)
}
render() {
return (
this.state.directLine ?
<ReactWebChat
directLine={this.state.directLine}
store={this.state.store}
/>
:
<div>Connecting to bot…</div>
)
}
}

How to redirect to another component from current component and also pass the props to redirect component in React

I have a note app. So basically the app adds, edit and delete notes.
For editing the note. I have to click the edit button of the note.
It should trigger a function which redirects to UpdateNote component
and also the Note ID should be passed to the Update component.
My Posts Component:
import React, { Component } from "react";
import axios from "axios";
import Post from "../../components/Post/Post";
class Posts extends Component {
state = {
posts: [],
error: false
};
fetchNotes = () => {
axios
.get("http://localhost:3001/notes")
.then(response => {
//console.log(response.data);
const posts = response.data;
this.setState({ posts: posts });
})
.catch(error => {
this.setState({ error: true });
});
};
componentDidMount() {
this.fetchNotes();
}
render() {
let posts = <p style={{ textAlign: "center" }}>Something went wrong!</p>;
if (this.state.posts.length === 0) {
posts = <p>Oops no post to show...</p>;
} else if (!this.state.error) {
posts = this.state.posts.map(post => {
//console.log(post._id);
return (
<Post
key={post._id}
title={post.title}
text={post.text}
id={post._id}
fetchNotes={this.fetchNotes}
edit={} // <-- HERE
/>
);
});
}
return <div>{posts}</div>;
}
}
export default Posts;
what should i pass in edit={} . so that it is redirected to update component and also the post_.id is passed to updatecomponent. Can any one help me.
Any kind of code suggestion would be really helpful
You'll probably want to navigate to a new route where your UpdateNote component is rendered, and that route should have the post._id as a url parameter. That way, your UpdateNote component will be able to get the post id from its route props.
So, if you're using React Router DOM, the edit prop on the post component will be the following function:
() => history.push(`${yourUpdateNoteRoute}${post._id}`)

How to get meta values in reactJs?

I am working on react application.I need meta tags value(description,title,etc).I am not able to access it.I need for navigator share api.My code is:
import React, { Component } from 'react';
import { Button } from 'semantic-ui-react'
class App extends Component {
constructor(props){
super(props);
this.getOpenGraphData = this.getOpenGraphData.bind(this);
}
getOpenGraphData(property){
return document.querySelector(`meta[property="${property}"]`)
.getAttribute('content');
}
handleClick(){
navigator.share({
title: getOpenGraphData('og:title'),
text: getOpenGraphData('og:description'),
url: getOpenGraphData('og:url')
})
.then(() => {
console.log('Successfully shared');
alert("successfully shared")
})
.catch((error) => console.log('Error sharing:', error));
}
render() {
return (
<div>
<Button content='Click Here' onClick={this.handleClick.bind(this)}/>
</div>
);
}
}
export default App;
But i am not able to access meta properties.Where I am doing wrong??
I think the issue is not with selecting the meta tag, but with navigator.share() as it is an experimental feature not fully supported by all browsers, check here.
You can check if navigator is supported before calling it:
if (navigator.share) {
navigator.share({...});
}

Resources