I'm trying to make a simple todo app in order to understand how frontend and backend are connected. I read some of the websites showing a tutorial for using and connecting rest API, express server, and database, but still, I was not able to get the fake data from a database. Anyway, I wanted to check if my understanding of how they are connected and talk to each other is correct or not. So could you give some advice please?
First of all, I'm planning to use either Javascript & HTML or React for frontend, Express for server, and Postgres for the database. My plan is a user can add & delete his or her task. I have already created a server in my index.js file and created a database using psql command. Now if I type "" it takes me to the page saying "Hello" (I made this endpoint), and I'm failing to seed my data to the database. Here are my questions↓
After I was able to seed my fake data into the database, how should I get the data from the database and send to the frontend? I think in my index.js file, create a new endpoint something like "app.get("/api/todo", (res, req) => ..." and inside of the callback function, I should write something like "select * from [table name]". Also, form the front end, I should probably access certain endpoints using fetch. Is this correct?
Also, how can I store data which is sent from the frontend? For example, if I type my new todo to <input> field and click the add <button>, what is the sequence of events looks like? Adding event listener to button and connect to the server, then create post method in the server and insert data, kind of (?) <= sorry this part it's super unclear for me.
Displaying task on the frontend is also unclear for me. If I use an object like {task: clean up my room, finished: false (or 0 ?)} in the front end, it makes sense but, when I start using the database, I'm confused about how to display items that are not completed yet. In order to display each task, I won't use GET method to get the data from the database, right?
Also, do I need to use knex to solve this type of problem? (or better to have knex and why?)
I think my problem is I kind of know what frontend, server, database for, but not clear how they are connected with each other...
I also drew some diagrams as well, so I hope it helps you to understand my vague questions...
how should I get the data from the database and send to the frontend?
I think in my index.js file, create a new endpoint something like
"app.get("/api/todo", (res, req) => ..." and inside of the callback
function, I should write something like "select * from [table name]".
Typically you use a controller -> service -> repository pattern:
The controller is a thin layer, it's basically the callback method you refer to. It just takes parameters from the request, and forwards the request to the service in the form of a method call (i.e. expose some methods on the service and call those methods). It takes the response from the service layer and returns it to the client. If the service layer throws custom exceptions, you also handle them here, and send an appropriate response to the client (error status code, custom message).
The service takes the request and forwards it to the repository. In this layer, you can perform any custom business logic (by delegating to other isolated services). Also, this layers will take care of throwing custom exceptions, e.g. when an item was not found in the database (throw new NotFoundException)
The repository layer connects to the database. This is where you put the custom db logic (queries like you mention), eg when using a library like https://node-postgres.com/. You don't put any other logic here, the repo is just a connector to the db.
Also, form the front end, I should probably access certain endpoints
using fetch. Is this correct?
Yes.
Also, how can I store data which is sent from the frontend? For
example, if I type my new todo to field and click the add , what is
the sequence of events looks like? Adding event listener to button and
connect to the server, then create post method in the server and
insert data, kind of (?) <= sorry this part it's super unclear for me.
You have a few options:
Form submit
Ajax request, serialize the data in the form manually and send a POST request through ajax. Since you're considering a client library like React, I suggest using this approach.
Displaying task on the frontend is also unclear for me. If I use an
object like {task: clean up my room, finished: false (or 0 ?)} in the
front end, it makes sense but, when I start using the database, I'm
confused about how to display items that are not completed yet. In
order to display each task, I won't use GET method to get the data
from the database, right?
If you want to use REST, it typically implies that you're not using backend MVC / server rendering. As you mentioned React, you're opting for keeping client state and syncing with the server over REST.
What it means is that you keep all state in the frontend (in memory / localstorage) and just sync with the server. Typically what is applied is what is referred to as optimistic rendering; i.e. you just manage state in the frontend as if the server didn't exist; yet when the server fails (you see this in the ajax response), you can show an error in the UI, and rollback state.
Alternatively you can use spinners that wait until the server sync is complete. It makes for less interesting user perceived performance, but is just as valid technical wise.
Also, do I need to use knex to solve this type of problem? (or better
to have knex and why?) I think my problem is I kind of know what
frontend, server, database for, but not clear how they are connected
with each other...
Doesn't really matter what you use. Personally I would go with the stack:
Node Express (REST), but could be Koa, Restify...
React / Redux client side
For the backend repo layer you can use Knex if you want to, I have used node-postgres which worked well for me.
Additional info:
I would encourage you to take a look at the following, if you're doubtful how to write the REST endpoints: https://www.youtube.com/watch?v=PgrP6r-cFUQ
After I was able to seed my fake data into the database, how should I get the data from the database and send to the frontend? I think in my index.js file, create a new endpoint something like "app.get("/api/todo", (res, req) => ..." and inside of the callback function, I should write something like "select * from [table name]". Also, form the front end, I should probably access certain endpoints using fetch. Is this correct?
You are right here, you need to create an endpoint in your server, which will be responsible for getting data from Database. This same endpoint has to be consumed by your Frontend application, in case you are planning to use ReactJS. As soon as your app loads, you need to get the current userID and make a fetch call to the above-created endpoint and fetch the list of todos/any data for that matter pertaining to the concerned user.
Also, how can I store data which is sent from the frontend? For example, if I type my new todo to field and click the add , what is the sequence of events looks like? Adding event listener to button and connect to the server, then create post method in the server and insert data, kind of (?) <= sorry this part it's super unclear for me.
Okay, so far, you have connected your frontend to your backend, started the application, user is present and you have fetched the list of todos, if any available for that particular user.
Now coming to adding new todo the most minimal flow would look something like this,
User types the data in a form and submits the form
There is a form submit handler which will take the form data
Check for validation for the form data
Call the POST endpoint with payload as the form data
This Post endpoint will be responsible for saving the form data to DB
If an existing todo is being modified, then this should be handled using a PATCH request (Updating the state, if task is completed or not)
The next and possibly the last thing would be to delete the task, you can have a DELETE endpoint to remove the todo item from the list of todos
Displaying task on the frontend is also unclear for me. If I use an object like {task: clean up my room, finished: false (or 0 ?)} in the front end, it makes sense but, when I start using the database, I'm confused about how to display items that are not completed yet. In order to display each task, I won't use GET method to get the data from the database, right?
Okay, so as soon as you load the frontend for the first time, you will make a GET call to the server and fetch the list of TODOS. Store this somewhere in the application, probably redux store or just the application local state.
Going by what you have suggested already,
{task: 'some task name', finished: false, id: '123'}
Now anytime there has to be any kind of interaction with any of the TODO item, either PATCH or DELETE, you would use the id for each TODO and call the respective endpoint.
Also, do I need to use knex to solve this type of problem? (or better to have knex and why?) I think my problem is I kind of know what frontend, server, database for, but not clear how they are connected with each other...
In a nutshell or in the most minimal sense, think of Frontend as the presentation layer and backend and DB as the application layer.
the overall game is of sending some kind of request and receiving some response for those sent requests. Frontend is what enables any end-user to create these so-called requests, the backend (server & database) is where these requests are processed and response is sent back to the presentational layer for the end user to be notified.
These explanations are very minimal to make sure you get the gist of it. Since this question almost revolves around the entire scope of web development. I would suggest you read a few articles about both these layers and how they connect with each other.
You should also spend some time understanding what is RESTful API. That should be a great help.
I want to simulate a micro blogging application to learn Angular 2.
I am using the following json placeholder links:
users
post
As you can see, the post api has userId, (and not username). If I have to display the user name while listing all post, would I require another API with both post and user name, or can it be done using two different calls to the above APIs?
This is the way I will be listing the post :-
<li *ngFor="let post of posts">
<div>{{post.userId}}</div>
<div>{{post.id}}</div>
<div>{{post.title}}</div>
<div>{{post.body}}</div>
</li>
As you can see, here based on the api call, I am getting userId...Instead of that I want it to display user's name
The way to do this in angular is using services. You don't directly call to an API from within your component. You need to create a "service" to deal with APIs, then inject your service in your component and consume them in there.
In your particular scenario, you will have two services, a "UserService" and a "PostService". Each of those services have a proper "get" method that calls to an API. Then in your component, you inject both those services and call their respective methods separately.
Regarding your specific update on the question, imagine you have a "posts" array and a "users" array after you have received your result from the API. Now, pay attention to the following logic:
for (let i=0; i<posts.length; i++)
{
posts[i].username = users.filter(u => u.id === posts[i].userId)[0].username
}
What we did here is iterating through all "posts" and adding a "username" attribute to each of them by cross referencing them to the users array. Just make sure you use the right syntax and case sensitivity as I have not tested this line and just included the logic in it
Both the options are viable..
You can create another API that responds with the required data. The new API can cal the controller functions of the previous API endpoints and return the data in the required format.
note: this is possible if you are working with your own server.
you can also chain the API calls if you want to work with the existing APIs.. Call the user api and then when you get the user details, in the subscribe handler, make another request to the posts API.
note the only problem i can see with this approach is the number of requests.. as there will be a posts request for each user.
In the End the decision is yours. you'll have to see the pros and cons.. If the server code is also yours, ill suggest the first approach..
I have searched and found something related to isolation level and "prevent dirty read". What I understood from my search was that I needed to isolate transaction level with READ COMMITED option (I am not sure about that though, still mysql begginner). What I want, however, is to make sure that when I get the information with SELECT it is, for sure, the updated information (the information could have been updated just instants ago and I would get the old info if I don't do anything about it...).
I think I understood the theory but I can't say the same about practice.
My old query was like this (js):
var query = "SELECT name FROM user_info WHERE id = "+user_id+"";
// doesn't solve my problem...
How can I perform what I want? Something like this?
var query = "SET TRANSACTION ISOLATION LEVEL READ COMMITED SELECT name FROM user_info WHERE id = "+user_id+"";
Thank you.
EDIT: (this might help explaining...)
The client is able to perform certain actions and I want to forbide clients from doing those multiple actions too fast. When a client action is sent to the server I check in db if the player is able to do the action or not. If the action is done I update the db so the player cannot act until some time has passed. If the player clicks too fast he sends multiple calls to the server and before the action state is updated in db the if conditional that checks in the db if the player can act returns true (he can do it) and it shouldn't. The info doesn't get updated fast enough.
I'm interfacing my App with Moodle and I'm successfully calling mod_scorm_get_scorm_sco_tracks and mod_scorm_get_scorm_attempt_count via Ajax (XMLHttpRequest) for a given user (userid).
Now I want my App to push some SCORM tracks back to Moodle.
So I'm trying to use mod_scorm_insert_scorm_tracks but with no success.
The problem is that this method does not take an userid parameter, so I don't understand how to use it (and if I try to add userid to input params I get an invalid parameter exception).
I had kind of success (no error message) by sending this:
scoid=206&attempt=2&tracks[0][element]=cmi.completion_status&tracks[0][value]=completed&tracks[1][element]=cmi.interactions.0.id&tracks[1][value]=multiplechoice_page_1_1&tracks[2][element]=cmi.interactions.0.learner_response&tracks[2][value]=White&tracks[3][element]=cmi.interactions.0.result&tracks[3][value]=correct&tracks[4][element]=cmi.interactions.0.description&tracks[4][value]=Which%20color%20was%20Garibaldi's%20white%20horse%3F&tracks[5][element]=cmi.interactions.1.id&tracks[5][value]=hotobject_page_2_1&tracks[6][element]=cmi.interactions.1.learner_response&tracks[6][value]=butterfly&tracks[7][element]=cmi.interactions.1.result&tracks[7][value]=incorrect&tracks[8][element]=cmi.interactions.1.description&tracks[8][value]=Where%20is%20the%20fish%3F&tracks[9][element]=cmi.score.max&tracks[9][value]=2&tracks[10][element]=cmi.score.raw&tracks[10][value]=1&tracks[11][element]=cmi.score.scaled&tracks[11][value]=0.5&tracks[12][element]=cmi.session_time&tracks[12][value]=PT0H0M15S&tracks[13][element]=timemodified&tracks[13][value]=1480947821&tracks[14][element]=userid&tracks[14][value]=26&tracks[15][element]=scoid&tracks[15][value]=206&wstoken=69f2471506c4c49ff47cd0de0c4c9f01&wsfunction=mod_scorm_insert_scorm_tracks&moodlewsrestformat=json
However, since I cannot specify the user those data belongs to, my user's attempts does not update (as predictable).
This is the response from Moodle:
{"trackids":[44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59],"warnings":[]}
I've tried inserting the userid info into traks (tracks[14][element]=userid&tracks[14][value]=26) but still no luck.
So, the questions are:
Which user are those tracks inserted to considering that I'm calling it from an external app, so there's no logged in user in Moodle?
How can I specify that those tracks are for a give userid?
the user identity comes from the HTTP Context of a full login into Moodle: you can't provide SCORM tracking info on behalf of any user but the actual logged-in user.
More at:
https://github.com/moodle/moodle/blob/d33c67bc4744f901bf389607cfbbb683ef1c7d80/mod/scorm/classes/external.php#L451
https://github.com/moodle/moodle/blob/0b8e0c374f89ca20e5b9e7c9370761810811edc6/lib/externallib.php#L481
HTH,
Matteo
I submitting an app to Facebook with open graph news read type by javascript.
All done so well with flow from user asking for authorized my app, and show the button help user can public the article then they can remove if they want to.
Today I got the request from Facebook need to change my app:
requirements
(https://developers.facebook.com/docs/opengraph/actions/builtin/#read).
Please make sure your users can (1) Turn sharing on/off globally on
each page an article appears. (2) Remove articles they shared within
your app on each page an article appears. (3) Only generate read
actions when you're sure someone is interested in reading the article
- only publish after 10 seconds.
The third request is easy just use timeout to show the button submit after user read article.
The seconds is so hard because I don't know how to full the array list of pass action of user doing with my app include action id and title of article they post which I can use to create "remove link" for each of them if user want to.
The fist request I did search for method of javascript to de-authorized the app from user (not revoke permission) so I can ask user to be reauthorized if they need.
Please help.
Beside I see very nice 2 sample in guild page
https://developers.facebook.com/attachment/OG_App_PublishToggle.png
https://developers.facebook.com/attachment/OG_App_DeleteActivity.png
But they din't give out the link of live site using it.
or may be that is one of Facebook markup similar "recommend box" , but how/where we can get it?
Please advices for the script or sample as Facebook dose will be help full
regards
UPDATE 1 I found the way to reauthorized all app or revoke one permission.
here the function:
var permsNeededPub = "publish_stream";
///notice that if permission is "publish_actions" revoke function not work
function xlfb_revokePerm() {
FB.api("/me/permissions", "delete",{permission:permsNeededPub}, function(response){
console.log(response);
if(response){
console.log(' Remove success '+permsNeededPub);
}
});
}
function xlfb_removeApp() {
FB.api("/me/permissions", "delete", function(response){
console.log("User removed the app from acount: "+response);
});
};
The seconds is so hard because I don't know how to full the array list of pass action of user doing with my app include action id and title of article they post which I can use to create "remove link" for each of them if user want to.
Whenever a user takes an OG action on your site - save the action_instance_id you are getting back from the API call and whatever extra data you might need to your database.
The fist request I did search for method of javascript to de-authorized the app from user (not revoke permission) so I can ask user to be reauthorized if they need.
Why would you want to de-authorize the app?
All that’s required here is to have a global on/off switch for all sharing activity – so if the user sets it to off, then you just don’t publish any actions for him as long as he leaves this setting set to off.