Giter VIP home page Giter VIP logo

devconnector_2.0's Introduction

DevConnector 2.0

Social network for developers

This is a MERN stack application from the "MERN Stack Front To Back" course on Udemy. It is a small social network app that includes authentication, profiles and forum posts.

Updates since course published

Such is the nature of software; things change frequently, newer more robust paradigms emerge and packages are continuously evolving. Hopefully the below will help you adjust your course code to manage the most notable changes.

The master branch of this repository contains all the changes and updates, so if you're following along with the lectures in the Udemy course and need reference code to compare against please checkout the origionalcoursecode branch. Much of the code in this master branch is compatible with course code but be aware that if you adopt some of the changes here, it may require other changes too.

After completing the course you may want to look through this branch and play about with the changes.

Changes to GitHub API authentication

Since the course was published, GitHub has deprecated authentication via URL query parameters You can get an access token by following these instructions For this app we don't need to add any permissions so don't select any in the scopes. DO NOT SHARE ANY TOKENS THAT HAVE PERMISSIONS This would leave your account or repositories vulnerable, depending on permissions set.

It would also be worth adding your default.json config file to .gitignore If git has been previously tracking your default.json file then...

git rm --cached config/default.json

Then add your token to the config file and confirm that the file is untracked with git status before pushing to GitHub. GitHub does have your back here though. If you accidentally push code to a repository that contains a valid access token, GitHub will revoke that token. Thanks GitHub πŸ™

You'll also need to change the options object in routes/api/profile.js where we make the request to the GitHub API to...

const options = {
  uri: encodeURI(
    `https://api.github.com/users/${req.params.username}/repos?per_page=5&sort=created:asc`
  ),
  method: 'GET',
  headers: {
    'user-agent': 'node.js',
    Authorization: `token ${config.get('githubToken')}`
  }
};

npm package request deprecated

As of 11th February 2020 request has been deprecated and is no longer maintained. We already use axios in the client so we can easily change the above fetching of a users GitHub repositories to use axios.

Install axios in the root of the project

npm i axios

We can then remove the client installation of axios.

cd client
npm uninstall axios

Client use of the axios module will be resolved in the root, so we can still use it in client.

Change the above GitHub API request to..

const uri = encodeURI(
  `https://api.github.com/users/${req.params.username}/repos?per_page=5&sort=created:asc`
);
const headers = {
  'user-agent': 'node.js',
  Authorization: `token ${config.get('githubToken')}`
};

const gitHubResponse = await axios.get(uri, { headers });

You can see the full change in routes/api/profile.js

uuid no longer has a default export

The npm package uuid no longer has a default export, so in our client/src/actions/alert.js we need to change the import and use of this package.

change

import uuid from 'uuid';

to

import { v4 as uuidv4 } from 'uuid';

And where we use it from

const id = uuid();

to

const id = uuidv4();

Addition of normalize-url package 🌎

Depending on what a user enters as their website or social links, we may not get a valid clickable url. For example a user may enter traversymedia.com or www.traversymedia.com which won't be a clickable valid url in the UI on the users profile page. To solve this we brought in normalize-url to well.. normalize the url.

Regardless of what the user enters it will ammend the url accordingly to make it valid (assuming the site exists). You can see the use here in routes/api/profile.js

Fix broken links in gravatar πŸ”—

There is an unresolved issue with the node-gravatar package, whereby the url is not valid. Fortunately we added normalize-url so we can use that to easily fix the issue. If you're not seeing Gravatar avatars showing in your app then most likely you need to implement this change. You can see the code use here in routes/api/users.js

Redux subscription to manage local storage πŸ“₯

The rules of redux say that our reducers should be pure and do just one thing.

If you're not familiar with the concept of pure functions, they must do the following..

  1. Return the same output given the same input.
  2. Have no side effects.

So our reducers are not the best place to manage local storage of our auth token. Ideally our action creators should also just dispatch actions, nothing else. So using these for additional side effects like setting authentication headers is not the best solution here.

Redux provides us with a store.subscribe listener that runs every time a state change occurs.

We can use this listener to watch our store and set our auth token in local storage and axios headers accordingly.

  • if there is a token - store it in local storage and set the headers.
  • if there is no token - token is null - remove it from storage and delete the headers.

The subscription can be seen in client/src/store.js

We also need to change our client/src/utils/setAuthToken.js so it now handles both the setting of the token in local storage and in axios headers. setauthToken.js in turn depends on client/src/utils/api.js where we create an instance of axios. So you will also need to grab that file.

With those two changes in place we can remove all setting of local storage from client/src/reducers/auth.js. And remove setting of the token in axios headers from client/src/actions/auth.js. This helps keep our code predictable, manageable and ultimately bug free.

Component reuse ♻️

The EditProfile and CreateProfile have been reduced to one component ProfileForm.js
The majority of this logic came from the refactrored EditProfile Component, which was initially changed to fix the issues with the use of useEffect we see in this component.

If you want to address the linter warnings in EditProfile then this is the component you are looking for.

Log user out on token expiration πŸ”

If the Json Web Token expires then it should log the user out and end the authentication of their session.

We can do this using a axios interceptor together paired with creating an instance of axios.
The interceptor, well... intercepts any response and checks the response from our api for a 401 status in the response.
ie. the token has now expired and is no longer valid, or no valid token was sent.
If such a status exists then we log out the user and clear the profile from redux state.

You can see the implementation of the interceptor and axios instance in utils/api.js

Creating an instance of axios also cleans up our action creators in actions/auth.js, actions/profile.js and actions/post.js

Note that implementing this change also requires that you use the updated code in utils/setAuthToken.js Which also in turn depends on utils/api.js I would also recommending updating to use a redux subscription to mange setting of the auth token in headers and local storage.

Remove Moment πŸ—‘οΈ

As some of you may be aware, Moment.js which react-moment depends on has since become legacy code.
The maintainers of Moment.js now recommend finding an alternative to their package.

Moment.js is a legacy project, now in maintenance mode.
In most cases, you should choose a different library.
For more details and recommendations, please see Project Status in the docs.
Thank you.

Some of you in the course have been having problems installing both packages and meeting peer dependencies.
We can instead use the browsers built in Intl API.
First create a utils/formatDate.js file, with the following code...

function formatDate(date) {
  return new Intl.DateTimeFormat().format(new Date(date));
}

export default formatDate;

Then in our Education.js component, import the new function...

import formatDate from '../../utils/formatDate';

And use it instead of Moment...

<td>
  {formatDate(edu.from)} - {edu.to ? formatDate(edu.to) : 'Now'}
</td>

So wherever you use <Moment /> you can change to use the formatDate function.
Files to change would be...

If you're updating your project you will now be able to uninstall react-moment and moment as project dependencies.

React Router V6 🧭

Since the course was released React Router has been updated to version 6 which includes some breaking changes. You can see the official migration guide from version 5 here .

To summarize the changes to the course code

Instead of a <Switch /> we now use a <Routes /> component.

The <Route /> component no longer receives a component prop, instead we pass a element prop which should be a React element i.e. JSX. Routing is also now relative to the component.

For redirection and Private routing we can no longer use <Redirect />, we now have available a <Navigate /> component.

We no longer have access to the match and history objects in our component props. Instead of the match object for routing parameters we can use the useParams hook, and in place of using the history object to push onto the router we can use the useNavigate hook.

The above changes do actually clean up the routing considerably with all application routing in one place in App.js. Our PrivateRoute is a good deal simpler now and no longer needs to use a render prop.

With moving all of the routing to App.js this did affect the styling as all routes needed to be inside the original <section className="container">. To solve this each page component in App.js (any child of a <Route />) gets wrapped in it's own <section className="container">, So we no longer need that in App.js. In most cases this just replaces the outer <Fragment /> in the component.

The styling also affected the <Alert /> component as this will show in addition to other page components adding it's own <section> would mean extra content shift when the alerts show. To solve this the alerts have been given their own styling so they are position: fixed; and we get no content shift, which additionally makes for a smoother UI with the alerts popping up in the top right of the screen.


Quick Start πŸš€

Add a default.json file in config folder with the following

{
  "mongoURI": "<your_mongoDB_Atlas_uri_with_credentials>",
  "jwtSecret": "secret",
  "githubToken": "<yoursecrectaccesstoken>"
}

Install server dependencies

npm install

Install client dependencies

cd client
npm install

Run both Express & React from root

npm run dev

Build for production

cd client
npm run build

Test production before deploy

After running a build in the client πŸ‘†, cd into the root of the project.
And run...

Linux/Unix

NODE_ENV=production node server.js

Windows Cmd Prompt or Powershell

$env:NODE_ENV="production"
node server.js

Check in browser on http://localhost:5000/

Deploy to Heroku

If you followed the sensible advice above and included config/default.json and config/production.json in your .gitignore file, then pushing to Heroku will omit your config files from the push.
However, Heroku needs these files for a successful build.
So how to get them to Heroku without commiting them to GitHub?

What I suggest you do is create a local only branch, lets call it production.

git checkout -b production

We can use this branch to deploy from, with our config files.

Add the config file...

git add -f config/production.json

This will track the file in git on this branch only. DON'T PUSH THE PRODUCTION BRANCH TO GITHUB

Commit...

git commit -m 'ready to deploy'

Create your Heroku project

heroku create

And push the local production branch to the remote heroku main branch.

git push heroku production:main

Now Heroku will have the config it needs to build the project.

Don't forget to make sure your production database is not whitelisted in MongoDB Atlas, otherwise the database connection will fail and your app will crash.

After deployment you can delete the production branch if you like.

git checkout main
git branch -D production

Or you can leave it to merge and push updates from another branch.
Make any changes you need on your main branch and merge those into your production branch.

git checkout production
git merge main

Once merged you can push to heroku as above and your site will rebuild and be updated.


App Info

Author

Brad Traversy Traversy Media

Version

2.0.0

License

This project is licensed under the MIT License

devconnector_2.0's People

Contributors

4hmaad avatar amirsolo avatar ashiqsultan avatar attriumph avatar austinmoore1492 avatar behnazz avatar bradtraversy avatar bushblade avatar codeghoul avatar coloradocolby avatar dependabot[bot] avatar developerkunal avatar diegomais avatar djacoby avatar eliasafara avatar islamgamal88 avatar jaqb8 avatar just-be-weird avatar kirasiris avatar koofng avatar luluhoc avatar mhtkar avatar nadershbib avatar nguyenda18 avatar ojself avatar omar-handouk avatar parkingmeter avatar ramneet-singh avatar samsam1414 avatar vincitore1402 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

devconnector_2.0's Issues

./src/components/profile-forms/EditProfile.js line 48

Brad,

In EditProfile I have changed line 48 to "}, [loading, getCurrentProfile]);"

Still I get a console warning:
./src/components/profile-forms/EditProfile.js
[1] Line 48: React Hook useEffect has missing dependencies: 'profile.bio', 'profile.company', 'profile.githubusername', 'profile.location', 'profile.skills', 'profile.social', 'profile.status', and 'profile.website'. Either include them or remove the dependency array. If 'setFormData' needs the current value of 'profile.company', you can also switch to useReducer instead of useState and read 'profile.company' in the reducer react-hooks/exhaustive-deps

What is the solution?

cannot read property 'id' of undefined

// @route DELETE api/profile
// @desc Delete api/profile, user & posts
// @access Private
router.delete('/', async (req, res) => {
try {
// @todo - remove users posts

//@Remove profile

await Profile.findOneAndRemove({ user: req.user.id });

//@Remove user
await User.findOneAndRemove({ _id: req.user.id });

res.json({ msg: 'User deleted' });

} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
module.exports = router;

Express Tye Error in server.js file

const app = express();
[0] ^
[0]
[0] TypeError: express is not a function
at Module._compile (internal/modules/cjs/loader.js:955:30)
[0] at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
[0] at Function.Module._load (internal/modules/cjs/loader.js:723:14)
[0] at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
[0] at internal/main/run_main_module.js:17:11
[0] [nodemon] app crashed - waiting for file changes before starting...

Comments.render

TypeError: Cannot read property 'map' of undefined
Comments.render
src/components/scream/Comments.js:27
24 | render() {
25 | const { comments, classes } = this.props;
26 | return (

27 |
| ^ 28 | {comments.map((comment, index) => {
29 | const { body, createdAt, userImage, userHandle } = comment;
30 | return (

Refreshing on /posts page brings user back to /dashboard

Refreshing on /posts page brings user back to /dashboard

I think this might be related to the pull request #75 as there is no longer a check for loading, so the user is redirected to /login and since he is now authenticated, the user is redirected again to /dashboard

Changing the JWT tokens time doesn't redirect to login page

Steps to re-produce go to the following path "routes\api\auth.js" and in jwt.sign object change the value of expiresin to something very close ie 20seconds now after signing in after 20 seonds the page is not getting expired after refresh only it will redirect user to login page

Found a bug on Register/Login

There's a bug I've found on user authentication. So, when you're registering or logging in you'll be redirected to the login page, not the dashboard page and returns 401 (Authorization denied). It means that the headers aren't received a token nor the token is null. Any idea?

Proxy not working

I have been stuck for a week trying to post to /api/users/register. I have followed the same steps as shown in the tutorials. The register api works fine when I register using postman.
My client package.json is the same as the one in the repository.
I have this on my onSubmit of Register form

axios
      .post('/api/users/register', newUser)
      .then(res => console.log(res.data))
      .catch(err => console.log(err))

newUser has all the form data i.e name email password and password2.
But I still get all four validation error from the server.
Help much needed please.

Issue when deleting entry from database. This state…filter is not an option? React Reducers

I currently have this in my reducer as initial state:

const initialState = {
  posts: [],
  post: null,
  loading: true,
  error: {}
};

and then I have this method:

case DELETE_POST:
      return {
        ...state,
        posts: state.posts.filter(post => post._id !== payload),
        loading: false
      };

Every time I delete an entry from my database, an error is displayed stating that 'state.pages.filter is not a function'. I've been struggling with this quite some time already. Any help will be really appreciated!.

Invalid Host header

After deployed to Heroku successfully, my website says "Invalid Host header", can anyone help? Thank you

Attempted import error: 'DashboardActions' is not exported from './DashboardActions'

First, I'm absolutely loving this tutorial! However, I'm running into an issue.

In order to get my app to compile, I have to add "export" to the function definition at the beginning of each of the different "sub-components." This includes, DashboardActions, Experience, and Education. I.E.
export const Education = ({ education, deleteEducation }) => {
Is there a reason it isn't recognizing the "default" as a valid export?

In doing this, everything seemed to be functioning as expected, until I got to adding the functionality to the delete buttons on the dashboard for the Experience/education tables. I end up with the error:

Warning: Failed prop type: The prop deleteExperience is marked as required in Experience, but its value is undefined.

In order to get it to compile, I did this to my Dashboard.js component:
import { getCurrentProfile, deleteEducation, deleteExperience } from '../../actions/profile';

...and further down...

<Fragment> <DashboardActions /> <Experience experience={profile.experience} deleteExperience={deleteExperience()} /> <Education education={profile.education} deleteEducation={deleteEducation()} /> </Fragment>

But the--somewhat expected--result of this is that when I click the delete button, it simply fires deleteEducation on the first available Education element in the array, and throws an error:

Unhandled Rejection (TypeError): Cannot read property 'statusText' of undefined
(anonymous function)
C:/Users/Name/DevConnector/client/src/actions/profile.js:157
154 | } catch (err) {
155 | dispatch({
156 | type: PROFILE_ERROR,
-> 157 | payload: { msg: err.response.statusText, status: err.response.status }
158 | });
159 | }
160 | };

I don't think its a coincidence, I'm noticing this behavior seems to be specific to the components I'm attempting to deploy WITHIN a component. I simply don't know enough about the workings of react to figure this thing out!

Does anyone know how to update by _id?

So I'm trying to create an Update by Id component using hooks. So far, I have created this route:
<PrivateRoute exact path="/admin/pages/update/:id" component={PageUpdate} />

Now in order to make it work and show the corresponding ID data. I have to use the match prop and then pass the match.params.id as a parameter into the function of getPost.

So far this is my code and it works when I preview the data corresponding to X Id using the Redux DevTools; in other hand, when I try to preview said data in the component, I can not see it.

This is my code:

import React, { useState, useEffect } from 'react';
import { Link, withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../../layout/Spinner';
import { getPost, updatePage } from '../../../actions/admin/page';

const Update = ({ getPost, updatePage, pages: { page, loading }, match, history }) => {

  const [formData, setFormData] = useState({
    text: '',
  });

  useEffect(() => {
    getPost(match.params.id);
    setFormData({
      text: !page ? '' : page.text,
    });

  }, [
      loading,
      // page,
      getPost,
      match.params.id
    ]);

  const {
    text,
  } = formData;

  const onChange = e =>
    setFormData({ ...formData, [e.target.name]: e.target.value });

  const onSubmit = e => {
    e.preventDefault();
    updatePage(formData, history, true);
  };

  console.log(text);

  return loading || page === null ? (
    <Spinner />
  ) : (
      <section className="mb-3">
        <div className="container-fluid">
          <h1 className="border-bottom-dark pb-3 mb-3">Update Your Page</h1>
          <small>* = required field</small>
          <form className="form" onSubmit={e => onSubmit(e)}>
            <div className="form-group">
              <textarea
                placeholder="Write here"
                name="text"
                autoComplete="text"
                className="form-control"
                value={text}
                onChange={e => onChange(e)}
              />
              <small className="form-text">So what are you up to?</small>
            </div>
            <div className="btn-group">
              <input type="submit" className="btn btn-primary my-1" />
              <Link className="btn btn-dark my-1" to="/admin/pages">Go Back</Link>
            </div>
          </form>
        </div>
      </section>
    );
};

Update.propTypes = {
  updatePage: PropTypes.func.isRequired,
  getPost: PropTypes.func.isRequired,
  pages: PropTypes.object.isRequired,
};

const mapStateToProps = state => ({
  pages: state.page
});

export default connect(
  mapStateToProps,
  { getPost, updatePage }
)(withRouter(Update));

NOTE: I have a console.log(text); and it does not shows anything, so I'm assuming the problem resides in the useEffect:

[
      loading,
      // page,
      getPost,
      match.params.id
    ]

As you can see I have the 'page' commented, if I uncommented, it makes the state run forever and displays the data that I want but it does not let me change it(probably because the 'page' keeps running forever).

Can somebody tell me where is my error? Thanks in advance.

UPDATE

I had to modify my first useEffect and had to create a second one in order to be able to retrieve and edit the displayed data in the component. Here it is the code:

// useEffect to call the specific _id
  useEffect(() => {
    getPost(match.params.id);
  }, [getPost, match.params.id]);

  // useEffect to display data corresponding to said _id
  useEffect(() => {
    const _page = page || {}
    setFormData((value) => ({ ...value, ..._page }))
  }, [page]);

This error comes in terminal while submitting empty create profile form.

Cannot set headers after they are sent to the client
[0] (node:13549) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[0] at ServerResponse.setHeader (_http_outgoing.js:470:11)
[0] at ServerResponse.header (/opt/lampp/htdocs/practice-stuff/DevConnector/node_modules/express/lib/response.js:771:10)
[0] at ServerResponse.send (/opt/lampp/htdocs/practice-stuff/DevConnector/node_modules/express/lib/response.js:170:12)
[0] at router.get (/opt/lampp/htdocs/practice-stuff/DevConnector/routes/api/profile.js:26:19)
[0] at process._tickCallback (internal/process/next_tick.js:68:7)

Cannot log in user

For some odd reason on the back-end I cannot log in, registration is fine. Ive changed the value of the x-auth-token as well. It user registered is stores upon MongoDB atlas. Ive checked the package.json to see if Bcrypt it working as well.
Below are screenshots of the errors I'm receiving as well as my code, seeking assistance to get this web application fully functioning. Please and thank you.
Screen Shot 2019-06-24 at 3 44 57 PM
Screen Shot 2019-06-24 at 3 45 31 PM
Screen Shot 2019-06-24 at 3 47 29 PM
Screen Shot 2019-06-24 at 3 49 10 PM
Screen Shot 2019-06-24 at 3 49 19 PM

uuid

Good afternoon, I was watching your tutorial in which I am currently at creating alerts in React with redux, but I have one issue:

Failed to compile.
[1]
[1] ./src/action/alert.js
[1] Attempted import error: 'uuid' does not contain a default export (imported as 'uuid').

Do you have any idea what is fix for this error?

Best regards,
Ivan Rener.

uuid

Hello, I would like to ask you something, yesterday I posted here an issue regarding uuid imports, well after my genius fix everything went down, I meant ID thing, so I restore main version of code from your github page, but error is showing once again, do you have any idea how should it be fixed?

Error:

./src/action/alert.js
Attempted import error: 'uuid' does not contain a default export (imported as 'uuid').

Best regards,
Sanady

nodejs cant connect to mongodb using mongoose

hi Brad, im getting the following error when trying to connect to my mongodb. do you have any idea why?

server running

MongoTimeoutError: Server selection timed out after 30000 ms at Timeout._onTimeout (/Users/ishakertem/Desktop/test/node_modules/mongodb/lib/core/sdam/server_selection.js:308:9) at listOnTimeout (internal/timers.js:536:17) at processTimers (internal/timers.js:480:7) { name: 'MongoTimeoutError', }

Got error with "CreateProfile" function

I got an error as the following:

[1] ./src/components/profile-forms/CreateProfile.js
[1] Line 228: 'CreateProfile' is not defined no-undef
[1] Line 239: 'CreateProfile' is not defined no-undef
[1]
[1] Search for the keywords to learn more about each error.
[0] Server started on port 5000
[0] Invalid connection string
[0] [nodemon] app crashed - waiting for file changes before starting...

but I found it in "../../actions/profile".

Spelling Error

client/src/actions/profile.js:236

pemanantly should be spelled permanently.

Thanks for your great course.

src/actions/profile

Hi everyone, I have this issue when going to 'Develo
Screen Shot 2019-11-06 at 2 18 58 PM
pers' tab, do you have any solution for this?

  42 |   } catch (err) {
  43 |     dispatch({
  44 |       type: PROFILE_ERROR,
> 45 |       payload: { msg: err.response.statusText, status: err.response.status }
  46 |     });
  47 |   }
  48 | };

also, I have an issue with posts

Posts
src/components/posts/Posts.js:9
   6 | import PostForm from './PostForm';
   7 | import { getPosts } from '../../actions/post';
   8 | 
>  9 | const Posts = ({ getPosts, post: { posts, loading } }) => {
  10 |   useEffect(() => {
  11 |     getPosts();
  12 |   }, [getPosts]);

Delete post by id error

Hi Brad,
I am trying to delete the post by id but on the postman I am getting server error. In the console terminal, it says cannot read property toString of undefined

In add Exp/Edu: If "to" field is filled, toggle "current" still record that data and send them.

In Add Experience/Education, if "To" field is filled, i.e. the user has already selected "to" date, toggling "Current" only disables the "To" field on the surface, while its value has already been recorded and to be sent to the server. As a result, when the user adds this experience, it is shown with a clear end date, e.g. "20/11/2019 - 25/11/2019" instead of "20/11/2019 - Now".

connectDB is not a function

I'm having the issue and I have it as exports, still not seeing connectDB as a function

my GitHub repo: https://github.com/aribambang/medusa

TypeError: connectDB is not a function
at Object. (/Users/aribambang/development/node/medusa/server.js:6:1)
at Module._compile (internal/modules/cjs/loader.js:759:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:770:10)
at Module.load (internal/modules/cjs/loader.js:628:32)
at Function.Module._load (internal/modules/cjs/loader.js:555:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:826:10)
at internal/main/run_main_module.js:17:11

connectDB();

Reducing lines of code

Hey Brad first off a big shout out to you to provide us with such amazing courses so easy to understand and learn.I would like to propose a small enhancement to the API handling functions.
I'd rather run a for in loop than destructuring.Anyways you know whats best and do let me know if you would like to me submit a pr on that I'll get working on it.

ProfileForm doesn't handle create/edit correctly

In ProfileForm.js (currently line 68) the createProfile call takes a boolean parameter "edit" to determine if this was a profile update (false means it is a newly created profile). In the current HEAD, this is always 'true' even for the creation flow.

createProfile(formData, history, true);

This affects the alert, where the "Profile updated" message is shown even for a newly created profile.
This also affects the redirect experience. As per the course, it was intended that the flow for a profile update will stay on the profile form component after the update in case the user wants/needs to make additional changes; where as a user creating a profile for the first time will be redirected to the dashboard after submission. Currently, if the user is creating there initial profile, they will remain in the ProfileForm component after submitting the form.

I am already working on a one line patch to resolve this issue.

setAlert is not a Function help about this isssue

this is my alert/actions file

import { v4 as uuidv4 } from 'uuid';
import { SET_ALERT, REMOVE_ALERT } from './types';

export const setAlert = (msg, alertType, timeout = 5000) => dispatch => {
const id = uuidv4();
dispatch({
type: SET_ALERT,
paylaod: { msg, alertType, id },
});
setTimeout(() => dispatch({ type: REMOVE_ALERT, paylaod: id }), timeout);
};

this is my Ragister File

`import React, { Fragment, useState } from 'react';
//import axios from 'axios';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { setAlert } from '../../actions/alert';
import PropTypes from 'prop-types';

export const Register = ({ setAlert }) => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
password2: '',
});
const { name, email, password, password2 } = formData;
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = async e => {
e.preventDefault();
if (password !== password2) {
setAlert('passowrds do not match', 'danger');
} else {
console.log('SUCCESS');
}
};
return (

Sign Up



Create Your Account


<form className="form" onSubmit={e => onSubmit(e)}>

<input
type="text"
placeholder="Name"
name="name"
value={name}
onChange={e => onChange(e)}
required
/>


<input
type="email"
placeholder="Email Address"
name="email"
value={email}
onChange={e => onChange(e)}
/>

This site uses Gravatar so if you want a profile image, use a
Gravatar email



<input
type="password"
placeholder="Password"
name="password"
value={password}
onChange={e => onChange(e)}
minLength={6}
/>


<input
type="password"
placeholder="Confirm Password"
name="password2"
value={password2}
onChange={e => onChange(e)}
minLength={6}
/>




Already have an account? Login In



);
};

Register.propType = {
setAlert: PropTypes.func.isRequired,
};
export default connect(null, { setAlert })(Register);

Token not cleared o logout

Token and User data is still present on logout .Steps to re-produce
Login with registered email id and password and click on logout .Now go to add-on redux tools if you check state two action were called clear_profile and logout .If you check state user data and token are still present now If you try to login with another user for some milliseconds it will show create profile button and after that it will show experience and another details.

/api/profile/me returns 400 after registration

I've just cloned repo, set mongodb uri, run both npm i and wanted to test your app. I registered without problems and got redirected to Dashboard with 'Create Profile' button. When I click it I get 400 from /api/profile/me with a response {"msg":"There is no profile for this user"}.

'map' undefined

Hey guys,

Actually I am taking the course, and I'm on lecture 52

The problem is... when I click the button to delete experience or education, web page shows

image
image
image

Well, there're three problems, but I'm sure they are related. There're some problems other students asked on the course page, but there's no solution yet. I think it is the problem of map(), not the profile.js problem, but I don't know how to correct it.

Thanks a lot if your guys can help me! I have stuck at this for hours now.

server error

hey guys, I am getting this "server error" I try everything I made sure the code exactly same (Server runing on port 5000
MongoDB Connected...
Illegal arguments: number, string)

Could not proxy request /api/users from localhost:3000 to http://localhost:5000/

I got this error here below after running npm run dev.

"Proxy error: Could not proxy request /api/users from localhost:3000 to http://localhost:5000/.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED)"

Unable to resolve it.
Note: I made sure that the the client and server is set to 5000. Here below is a
copy of the client code.
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"moment": "^2.24.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-moment": "^0.9.2",
"react-redux": "^7.0.2",
"react-router-dom": "^5.0.0",
"react-scripts": "3.0.0",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"uuid": "^3.3.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:5000"
}

server side here below:

const express = require('express');
const connectDB = require('./config/db');
const path = require('path');

const app = express();

// Connect Database
connectDB();

// Init Middleware
app.use(express.json({ extended: false }));

// Define Routes
app.use('/api/users', require('./routes/api/users'));
app.use('/api/auth', require('./routes/api/auth'));
app.use('/api/profile', require('./routes/api/profile'));
app.use('/api/posts', require('./routes/api/posts'));

// Serve static assets in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));

app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log(Server started on port ${PORT}));

mobile Devconnector

Has anyone tried to make a mobile Devconnector?
I mean create a mobile app, and connect it to the devconnector's api and database. React Native or Flutter would be awesome!

Warning: componentWillMount has been renamed

I completed the course up until the deployment, and stopped to clean up various console warnings in dev tools. I was able to take care of all of them except for the following two. Does anyone know what dependency might be causing these (if one of them is the cause) or what can be done about it?

Warning: componentWillMount has been renamed, and is not recommended for use.

Warning: componentWillReceiveProps has been renamed, and is not recommended for use.

Compiled with warnings

Brad,

I've ran the install on demo and hooked it up to a fresh db. so everything is clean and i get these warnings in the terminal.

Compiled with warnings.

./src/components/profile/ProfileGithub.js
Line 10: React Hook useEffect has a missing dependency: 'username'. Either include it or remove the dependency array react-hooks/exhaustive-deps

./src/components/post/Post.js
Line 14: React Hook useEffect has a missing dependency: 'match.params.id'. Either include it or remove the dependency array react-hooks/exhaustive-deps

./src/actions/post.js
Line 158: 'res' is assigned a value but never used no-unused-vars

./src/components/post/CommentItem.js
Line 1: 'Fragment' is defined but never used no-unused-vars

./src/components/profile-forms/EditProfile.js
Line 48: React Hook useEffect has missing dependencies: 'profile.bio', 'profile.company', 'profile.githubusername', 'profile.location', 'profile.skills', 'profile.social', 'profile.status', and 'profile.website'. Either include them or remove the dependency array. If 'setFormData' needs the current value of 'profile.company', you can also switch to useReducer instead of useState and read 'profile.company' in the reducer react-hooks/exhaustive-deps

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.