Dealing with user profile related stuff in React.js and Phoenix

Hello!

I’m trying to build a website, where users can post their stuff online… I’m using Phoenix & React.js. The problem I’m facing is, I’ve no idea how to load the user profile info. For example, when an user types https://example.com/user/someusername in the browser, I would like to load that profile of that particular user in React.js. If the user is on the home page and wants to view certain user profile, I can send an XHR request(also assign a x-requested-with request header as XMLHTTPRequest) to api server and load the user related data(via JSON response) and update the page using React(and React-Router). The real problem is how should I load the user profile content when the user wants to view certain profile with out XHR i.e., plain get request in a new tab or a new window(it doesn’t really matter) for example - GET https://example.com/user/someusername. I know how to send a phoenix template for a particular route when there is a plain HTTP get request, but I don’t know how to do it using React. For example take instagram & twitter(they are using React.js for their frontend stuff), they are loading user content(profile stuff like followers, following, likes etc…,), how are they loading the content for a particular profile, I don’t see they are making additional api calls to the server when there is direct request for a particular page.

I hope I made some sense.

I would be grateful if you could shed some light on this, I’ve been stuck with this problem for the last couple of days…

Thank you very much for taking time to read my question.

If I understand correctly what you mean, you want to pick up data (sone user data in your case) on the client side within react.

One way you can achieve this without making a separate client side request would be do have an html tag with the serialised data inside of it. Something like this in your template.


<div data-user="<%= Jason.encode(%{ username: some_user_name) %>" />

And then grab it inside the JS from this div when the page loaded and parse it with JSON.parse()

Yeah I already figured it out the solution, but I’m too lazy to post it here …

For the future readers - here’s the solution,

Instagram is sending the initial data in a json format inside a script tag … that’s the same solution I’m going to use for my app.

How did I figured it out? I blocked certain page requests using https://github.com/clupasq/ChromeHttpRequestBlocker and it gave me some insights.

Thank you @benlime for your answer and time. Have a nice day and Take care.

Another solution in case you don’t want SSR, or you’re doing static builds, a easy way to do it is:

  • Assuming you have a route like <Route path="/the_route/:slug" component={YourViewComponent} />

Then on the YourViewComponent

import React, { useState, useEffect }  from "react";
import Spinner  from "../../../components/global/Spinner.js";

const axios = require("axios");

export default function YourViewComponent({ match: { params: { slug } }, history }) {
    const [loading, set_loading] = useState(true);
    const [request_loading, set_request_loading] = useState(false);
    const [user_profile, set_user_profile] = useState(false);
    const [no_user, set_no_user] = useState(false);

    useEffect(() => {
        if ((!user || slug !== user_profile.slug) && !request_loading && !no_user) {
            get_user_profile(slug);
        }
    }, [slug, user_profile, request_loading]);

    function get_user_profile(slug) {
        set_request_loading(true);
        set_loading(true);
        set_no_user(false);
        axios({
            method: "GET",
            url: `${BACKEND_URL()}/user_profile/${slug}`
        })
        .then(({data}) => {
            if (data.success) {
                set_user_profile(data.user_profile);
            } else {
                set_no_user(true);
                set_user_profile(false);
            }
            set_loading(false);
            set_request_loading(false);
        })
        .catch((e) => {
            set_loading(false);
            set_request_loading(false);
            set_user_profile(false);
            set_no_user(true);
        });
    };

    return (
        loading ?
        <Spinner classes="spinner-full" /> :
        no_user ?
        <div><p>Couldn't find user with {slug} slug</p></div> :
        <div>
            <p>User {slug} found...</p>
        </div>
    );
};

You could remove the no_user thing and just use history to redirect to an error page instead.

1 Like

hey man, thanks for taking the time to answer my question, I very much appreciate it! :slight_smile:

1 Like

hey, yw, hope it helps!