Giter Site home page Giter Site logo

fullstackopen-2019.github.io's People

Contributors

alirezaghey avatar copperii avatar cxcorp avatar granigan avatar guymelef avatar hajame avatar jasumoi avatar jleppane avatar jose-donato avatar juhq avatar marklaatikainen avatar mdboticano avatar micpob avatar minzen avatar mluukkai avatar mremes avatar msaari avatar niinasaarelainen avatar nurou avatar ollesetta avatar palcsta avatar pekkast avatar rpajunen avatar skaipio avatar sparlos avatar tamasmlnr avatar teijatestaaja avatar timiscoding avatar vkopio avatar vulle5 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

fullstackopen-2019.github.io's Issues

Please explain noteService import in Notes Project

On part 2 of the notes project, there is an import from the services file that looks like this:
import noteService from './services/notes'

But there is no component or method in the notes file by this name.

Not sure if i'm totally missing something here, but could please explain why this is actually working?

Header menu confusing for slow internet.

Hello,
I just got a little issue with the i18n of the header menu when i switch to English from the main page the content of the pages quickly loads the English version but the menu takes time to update due to my slow internet so when i click on the FAQ i get the FI version not the ENG one.

Part 4a table of contents anchor link to second exercises does not work

In Part 4a, there are two "Exercises" section, and thus two table of contents sidebar links to exercises. The table of contents sidebar link to the second exercises does not work, because the same ID is generated for both exercise sections in the document.

A possible solution: Could the markdown-to-HTML generator take into consideration repeat Headings and append a -2 onto the end of the second exercise section ID, making it distinct?

part2-4 causes "Cross-Origin Request Blocked"

I am using Docker and my browser is not at localhost, and I need to use Docker ip 172.17.0.2

When trying to connect to the json-server with axios, I get error in browser:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://172.17.0.2:3001/notes. (Reason: CORS request did not succeed).

This can be overridden by using the JSONP (npm install --save axios-jsonp)
And changing the App.js code:
..
import jsonpAdapter from 'axios-jsonp'
..
useEffect(() => {
axios({
url: 'http://172.17.0.2:3001/notes',
adapter: jsonpAdapter
}).then(response => {
setNotes(response.data)
})
}, [])

part 3d validation on update

Mongoose doesn't run validation on default when updating objects and needs to be run with the runValidators: true option. This should be mentioned in exercise 3.19.

Cloning part3-1 causes MongooseError

I have tried to keep it succinct.
In order to start part 3, I thought it necessary to clone this repository with its respective npm install && npm start.

However, doing this returns a MongooseError which goes:
message: 'The 'uri' parameter to 'openUri()' must be a string, got "undefined". Make sure the first parameter to 'mongoose.connect()' or 'mongoose.createConnection()' is a string.', name: 'MongooseError'

What do I do? 😨

Part 3c -> put request for updating a note -> note vs new Note

This took my a while to figure out (Googling also didn't help much) - the reasoning behind creating a note object rather than using a model constructor.

I suggest mentioning that using the Note model constructor initiates it with an _id key, so that when attempting to update Mongo will be pissed and throw an error.

Great course by the way!

Cannot hover or click on links through invisible header

The header bar goes invisible when the user scrolls down, but captures pointer/touch events.

(Some of us like to read with the content right up against the top of the browser viewport 😛 )

Expected Behavior: The user would be able to click on a link right up against the top of the page if it is visible.

Observed Behavior: The user cannot click on a link that is beneath the invisible header.

Steps to Reproduce:

  1. Go to https://fullstackopen.com/en/part0/fundamentals_of_web_apps
  2. Scroll down (causing the header to fade to invisible)
  3. Scroll down until a link is right up against the top of the viewport
  4. Attempt to hover or click on the link
  5. Observe that even though the link is clearly visible, hovering and clicking on the link does not work.

Possible Fix: Would it be a simple fix to make the header pass on touch/pointer events while it's in its hidden state?

Cannot click on link under the header

Explain about no need closing DB connection in part 3c

After the part

The public interface of the module is defined by setting a value to the module.exports variable. We will set the value to be the Note model. The other things defined inside of the module, like the variables mongoose and url will not be accessible or visible to users of the module.

there's no explicit closure of DB connection.

Please explain why there's no mongoose.connection.close() any more although it's specifically highlighted that it should be done.

Part 4b: expect().toEqual() fails, comparing raw Date to string

Problem

In part 4b, the section Error handling and async/await contains a test that will fail:

test('a specific note can be viewed', async () => {
  const notesAtStart = await helper.notesInDb()

  const noteToView = notesAtStart[0]

  const resultNote = await api
    .get(`/api/notes/${noteToView.id}`)
    .expect(200)
    .expect('Content-Type', /application\/json/)

  expect(resultNote.body).toEqual(noteToView)
})

Specifically, Jest will take issue with the way the note's date is formatted:

    expect(received).toEqual(expected) // deep equality

    - Expected
    + Received

      Object {
        "content": "HTML is easy",
    -   "date": 2020-01-22T05:06:35.866Z,
    +   "date": "2020-01-22T05:06:35.866Z",
        "id": "5e27d85dc41be71f7cfd1ff6",
        "important": false,
      }

I'm not a Javascript wizard (hence why I'm taking this course), but it seems like Express really wants to parse the date field as a string, whereas MongoDB will return a raw Date as expected.

Proposed Solution

Modify the noteSchema's toJSON() transform to convert the date to a string when necessary:

noteSchema.set('toJSON', {
  transform: (document, returnedObject) => {
    returnedObject.id = returnedObject._id.toString()
    returnedObject.date = returnedObject.date.toString()
    delete returnedObject._id
    delete returnedObject.__v
  }
})

Or, maybe I'm dumb and missed something in the text. Either way wanted to bring this up.

Part 1c: Is lifting state up preferably to the App root component right?

On Part 1.c, topic passing state to child components, it is said that :

One best practice in React is to lift the state up as high as possible in the component hierarchy, preferably to the App root component.

I think this my be misleading to many newcomers to React, it implies that the best place for all state to reside in on the App root component, which is not what the reactjs docs says about. It explicit says that state should be lifted to highest common ancestor to two components that use that state.

Recommending that state preferably resides on the App root would lead to many useless re-renders of components passing down prop changes to it's children and force many components to "know" about states that don't have anything to do with them.

I think it would be better to say that state should reside on the highest common ancestor and latter when a example with a deeper component tree is shown reintroduce the concept showing a refactor to highest common ancestor. (Similar to what is done on reactjs documentation

Something is missing in the instructions for anecdotes [step 2 and 3]

I think useState for complex data structures is not being explained adequately. There needs to be multiple values in the state to store votes for each anecdote, but the starter code only shows a single vote and setVote. It isn't clear how to set up state as an object that can handle this.

" if you decide to store the votes of each anecdote into an array or object in the component's state, you should refer to the material to see the correct way of updating state stored in complex data structures like objects and arrays."

The emphasized phrasing here tells us there is a way to do this without storing an object or array in the state. But this not clear.

The example code in the Complex State section doesn't really help, since

"Storing all of the state in a single state object is a bad choice for this particular application; there's no apparent benefit and the resulting application is a lot more complex".

The example in the Handling Arrays section is also not really applicable to the exercise. It shows how to have an array that can accept two different values, but each value needs its own function. I'm assuming that creating a function for each anecdote would not be optimal, but that's the only solution that the readers are led to from the guide.

I think kicking the user to the React docs to figure this out defeats the purpose of having a course. Please let me know if there are any revisions to this section in progress. Thanks.

Part 1: Missing "Button" component in solutions

In Exercise 1.10: unicafe step5 it says

Extract the following two components:

- Button for defining the buttons used for submitting feedback
- Statistic for displaying a single statistic, e.g. the average score.

The solution of part 1, however, doesn't include the Button component and instead renders normal jsx buttons inside of the App component.

Part 3a Part 2 API url differences

In exercise for Part 3a, we create an API with url /api/persons but the previous Phonebook exercise in Part 2 uses url /persons.
Could there be more instructions to explicitly change url in phonebook before continuing from part 3a to part 3b?

npm run build:ui not working on Windows 10

As stated in the title, the npm run build:ui command does not work in Windows 10 CMD.

Propose adding reference to a Windows friendly command. In my experience, the following command works with the directory structure:

-- course
-- -- part 2 (frontend)
-- -- part 3 (backend)

"build:ui": "rmdir build /s /q && cd ../part2 && npm run build && xcopy build ..\\part3\\build /s /e /y /i",

Header.scss header class has duplicate property

transition is defined twice in Header.scss. I'm guessing the second one should stay since it was overwriting the first one anyway.

.header {
  ...
  transition: top 0.2s ease-in-out;
  ...
  transition: all 0.2s ease-in-out;
}

Part 8e: "Cannot read property 'headers' of undefined"

While I was working on exercises from part 8e, I stumbled upon this error "Cannot read property 'headers' of undefined" while trying to listen to a subscription in GraphQL interface on localhost:4000. I managed to fix it like this:

        const auth = req && req.headers.authorization ? req.headers.authorization : null;

For WS requests req object is undefined, so this code from previous parts

        const auth = req.headers.authorization ? req.headers.authorization : null;

gives error

Scroll jank after clicking go up button

I'm using Chrome Version 79.0.3945.88, and I found that scrolling becomes janky and stuttering after clicking the arrow to return to the top of the page in the course contents. This scrolling behavior is only apparent in the course contents pages. When I navigate to other pages on the site ("About course", "FAQ", etc) after clicking the arrow button, scrolling is normal. Scrolling returns to normal on the course contents pages after refreshing.

Tilallisen komponentin setTimeout-ongelma

Ensinnäkin kiitos hienosta kurssista ja terveisiä CRA-tiimiltä 👋

Kävin omaksi iloksi kurssia lävitse ja huomasin seuraavan (todella yleisen) footgunin:

Kohdassa Tilallinen komponentti käytetään setTimeout metodia kutsumaan setState funktiota laskurin korottamiseksi:

import React, { useState } from 'react'
import ReactDOM from 'react-dom'

const App = (props) => {
  const [ counter, setCounter ] = useState(0)

  setTimeout(
    () => setCounter(counter + 1),
    1000
  )

  return (
    <div>{counter}</div>
  )
}

ReactDOM.render(
  <App />, 
  document.getElementById('root')
)

Esimerkissä ei sinällään ole vikaa ja se toimii hyvin, mutta jos komponenttia muokataan hieman tosi elämän usecasen suuntaan huomataan seuraava lifecycle-ongelma:

https://codesandbox.io/s/j28p3xz229

import React, { useState } from 'react'
import ReactDOM from 'react-dom'

const Counter = (props) => {
  const [counter, setCounter] = useState(0)

  setTimeout(
    () => setCounter(counter + 1),
    100
  )

  return (
    <div>{counter}</div>
  )
}

function App() {
  const [x, set ] = useState(true)
  
  return <div onClick={() => set(false)}>
    {x ? <Counter /> : null}
  </div>
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

Klikatessa laskuria silloin tällöin konsoliin nousee seuraava virheilmoitus:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

React poisti (unmount) <Counter /> komponentin, mutta sitä vasten silti kutsuttiin setStatea koska sitä ei ollut siistitty. setTimeoutin (kuten myös varsinkin setIntervalin) käyttö on harmittavan epätriviaalia, mutta laskurin siistiminen useEffect-hookia käyttäen on mahdollista vaikkapa seuraavaan tyyliin:

https://codesandbox.io/s/j28p3xz229

import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'

const Counter = (props) => {
  const [counter, setCounter] = useState(0)
  useEffect(() => {
    const x = setTimeout(
      () => setCounter(counter + 1),
      100
    )

    return () => clearTimeout(x)
  }, [counter])

  return (
    <div>{counter}</div>
  )
}

function App() {
  const [x, set ] = useState(true)
  
  return <div onClick={() => set(false)}>
    {x ? <Counter /> : null}
  </div>
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

useEffect-hookia kutsutaan kun komponetti on mountattu ja siitä palautuvaa funktiota kun unmount-tapahtuu, joka korjaa ongelman. useEffectille pitää kuitenkin syöttää muuttujan counter arvo arrayssä, jotta React uudelleen ajaa efektin kun arvo päivittyy.

Tuossa voisi olla hyvä sauma avata vähän Reactin lifecycleä, joka on olennainen osa (ja ehkä suurin päänvaiva) Reactia 😃 Samaa kaavaa käyttää myös Reactin omat ohjeet

Definition of NB on General Info

Hello.

I saw many times the NB abbreviation through the course pages and I never knew what his meaning was until I searched on Wikipedia.
Maybe I'm a bit ignorant but this is the first time I see this abbreviation.

Could it be added a slightly reminder to emphasize when a NB note is seen?
On General Info page for example.

I think the notes are very useful like all the course material.

Part 6b - Switch from "connect", "mapStateToProps", and "mapDispatchToProps" methods to useSelector() and useDispatch()

With the introduction of hooks, i find it much easier to use the new "useSelector()" and "useDispatch()" methods to create redux actions and access the redux state. Since the course uses functional components and hooks over the traditional class component, I think using the new redux hooks would fall right inline with the curriculum.

For example, to access notes in the redux state:

import React from 'react'
import { useSelector } from 'react-redux'

export const NotesComponent = () => {
  const notes = useSelector(state => state.notes)
  return <div>{notes}</div>
}

Redux Hooks

[Security] Do not store auth token in localStorage

It is not safe to store sensitive data in localStorage. LocalStorage is readable by JavaScript, which in this case has been its intended purpose. However that's not how you do a secure authentication system.

Consider the following:

  • your platform has a feature for users to "post" text. This could lead to an XSS attack therefore compromising all tokens for every user.
  • your platform could make use of npm packages. This could lead you to an attack type where a dependency can manipulate data on your webpage. This leads to compromising of all tokens for every user. [1]
  • your platform could have links to 3rd party JavaScript. This could be analytics, advertisements, and/or JavaScript libraries like jQuery. An attack on their services could be an attack on yours. Therefore compromising all tokes for every user. (Remember: they may also use npm)
  • An user could have a malicious browser extension that can inject JavaScript and grab the token.

How to overcome this?
Use cookies. Especially httpOnly cookies with the secure flag. They've been battle-tested for decades now. The httpOnly flag tells the browser to never give JavaScript access to the cookie value. The secure flag tells the browser to never send the cookie to an unencrypted site.

"But this wont work since we're using React, right?"
Wrong. You can still serve your users a SPA site with a login page. The login page will make an XHR request to the backend API endpoint with the username and password as POST parameters. The server will respond with the user data if successful and with an error message if not.

That's it. That's how easy it is.

"Wait what happens if I reload the page?"
Well the page will reload but you are still logged in. How? Well the magic is in the session cookie. The server sent you the user data on the body, but the header information contained the cookie which your SPA JavaScript never saw. The client browser just grabbed the cookie automatically and stores it. It also sends it back to the server an all further requests. If the session dies or is not set, the backend will respond with an error asking for authentication and the client can display it in a nice, meaningful way.

Additionally, the cookie most likely has to have SameSite flag set to Lax for this to work. One could also host the SPA page from static file host such as GitHub Pages or Amazon S3 but have the backend endpoint on a subdomain and on a separate server somewhere else. For that to be secure some CORS headers would be necessary.

[1] https://www.theregister.co.uk/2018/11/26/npm_repo_bitcoin_stealer/

Part 2 C : Exercises 2.12* JS Array Filter Method Change

Use .startsWith instead of .indexOf method for filtering arrays composed of objects with details of a country because normal usage assumes the user putting in the name from the starts.

Plus, it teaches one more array method to learners.

Different chat channels for Full Stack Open

Hi there,

I think it would be a big help to have separate channels for different topics e.g Part 1 help, English help, Finnish help etc. Currently it's difficult to navigate between the comments since everything is in one channel.

Are there any plans to migrate away from Telegram to something like that supports different channel topics like Slack/Discord/Gitter?

Exercise 4.14 is missing

Not sure if the exercise is missing or the numbering is off but it seems like 4.14 does not exist

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.