How to Render a Field Request Without Refreshing the Page

How to render a field request without refreshing the page?

We'll use ajax, with jQuery so be sure you have jQuery before you read.

first, you've to create an endpoint to GET, go to urls.py & add an endpoint say

path('/myserver/getID/', views.get_employee_name, name="whatever")

now, this calls get_employee_name right? Let's now call it in JS without refreshing.

here's the basic syntax ->

$.ajax({THIS IS A SIMPLE DICT})

ajax takes parameters

  • type which is the request type
  • url which is the request URL which we just made above (not the full url, you're specifying the endpoint from where you're located on the website so you just use /myserver/getID/)
  • it also takes data which is a dictionary with your posted data (yes a dictionary inside the bigger ajax dictionary
  • it CAN take success which is a function to call after getting the response with status 200 (success) and that success function can have the parameter response which is your response
  • it CAN take error which is a function that gets called after an error & takes error as argument

enough talking...

$.ajax({
url: 'myserver/getID',
type: 'GET',
data: // don't specify this, we're not posting any data,
success: function (response) {console.log(response.data)}, //this will be what returned from python
error: function (error){console.log(error)}
})

this is a simple ajax request

NOTE, if you return a redirect from python & accept it from ajax, it won't work, ajax can't redirect, be sure to remember that because most of the time people ask why redirect('mylink') doesn't work after I return it from ajax.

Another NOTE is the when dealing with post requests with ajax, you must include the csrf token which can be included by

csrfmiddlewaretoken: '{%csrf_token%}'

You can use Fetch API too if you want, or even normal XMLhttprequest.

How can I re-render to display changes without refreshing the page?

It happens because you set EITHER the foodList OR the searchedFoodList in your updateFoodName function right here:

const updateFoodName = (id) => {
if (newFoodName) {
Axios.put("https://project.herokuapp.com/update", {
id: id,
newFoodName: newFoodName,
})
.then(() => {
props.searchedFood.length > 0 // <-- HERE
? props.setSearchedFood(/* ... */)
: props.setFoodList(/* ... */);
})
.catch((error) => console.log(`Update name failed: ${error}`));
}
};

What you really want to do is update both either way:

const updateFoodName = (id) => {
if (newFoodName) {
Axios.put("https://project.herokuapp.com/update", {
id: id,
newFoodName: newFoodName,
})
.then(() => {
// NO IF HERE
props.setSearchedFood(/* ... */)
props.setFoodList(/* ... */);
})
.catch((error) => console.log(`Update name failed: ${error}`));
}
};

If you don't update both, you will not see the changes when foodList is shown, because the new data never had a chance to get there.


If I can propose changes: I would only ever change the foodList and calculate the filtered list using a filter state on every change. This way, you only ever have to change data in one place, which would have avoided confusions like this.

Here is a small prototype of what I would mean:

const App = () => {
const [foodList, setFoodList] = useState([]);
const [filter, setFilter] = useState("");

const filteredFoodList = useMemo(() => foodList.filter(/*...*/), [
foodList,
filter
]);

return (
filteredFoodList.map(/*...*/)
);
}

How to reload a component without refreshing the entire page?

If the quote is to show a new quote without refreshing the entire page, remove the axios request from the hook and put it in its own function.

  const getQuotes = () => {
axios
.get("https://geek-jokes.sameerkumar.website/api?format=json")
.then(res => {
setQuotes(res.data);
// console.log(res.data);
})
.catch(err => console.log(err));
}

// ...

<Buttons onClick={getQuotes} quotes={quotes} />

Then adjust the button to get use this function when it's clicked:

const Buttons = ({ quotes, getNewQuote, onClick }) => {

// ...

<button id="new-quote" onClick={onClick}>
New Quote
</button>

You might want to add an animation while it's retrieving things as well with a useState for loading, but this should be a good start.

======= UPDATE =======

Here's also an example code to see how it could work.
Click Run code snippet to see it working.

const { useState, useEffect } = React;

const Quote = props => {
return <section>
<blockquote>
{JSON.stringify(props.quote)}
</blockquote>
<button onClick={props.onClick}>Get Quote</button>
</section>
}

const App = () => {
const [quotes, setQuotes] = useState(null);
const [loading, setLoading] = useState(true);

const getQuotes = () => {
setLoading(true);
axios
.get("https://geek-jokes.sameerkumar.website/api?format=json")
.then(res => {
if (res.data && res.data.joke) {
setQuotes(res.data.joke);
}
setLoading(false);
})
.catch(err => {
console.log(err);
setLoading(false);
});
}

useEffect(() => {
getQuotes();
}, []);

return loading ? <p>Loading...</p> : <Quote quote={quotes} onClick={getQuotes} />
}

ReactDOM.render(<App />, document.querySelector('#root'));
body {
background: #efefef;
font-family: Arial, sans-serif;
padding: 20px;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}

section {
background: white;
border-radius: 6px;
display: block;
padding: 10px;
}

blockquote {
padding: 10px;
margin: 0 0 10px 0;
border-bottom: 1px solid #efefef;
font-size: 21px;
}

button {
border-radius: 4px;
background: blue;
color: white;
border: none;
height: 40px;
padding: 0 12px;
font-size: 14px;
}

p {
display: block;
max-width: 80px;
background: white;
border-radius: 6px;
padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios@0.19.2/dist/axios.min.js"></script>

<div id="root"></div>

Update data on a page without refreshing

This is typically achieved with a technique called AJAX. This technique loads data asynchronously (in the background) so it can update your content without needing to reload the page.

The easiest way to implement AJAX is with the jQuery load() method. This method provides a simple way to load data asynchronous from a web server and place the returned HTML into the selected element. The basic syntax of this method is: $(selector).load(url, data, complete); where the arguments are:

  • selector the existing HTML element you want to load the data into
  • url a string containing the URL to which the request is sent
  • data (optional) a plain object or string that is sent to the server with the request
  • complete (optional) a callback function that is executed when the request completes

The required URL parameter specifies the URL of the file you want to load.
The optional data parameter allows you to specify data (i.e. key/value pairs) that is sent to the web server along with the request. The optional complete parameter can be used to reference a callback function. The callback is fired once for each selected element.

A visualisation:

visualization

A simple example of using load(), where we load data dynamically when a button is pressed:

DEMO

// no need to specify document ready
$(function(){

// optional: don't cache ajax to force the content to be fresh
$.ajaxSetup ({
cache: false
});

// specify loading spinner
var spinner = "<img src='http://i.imgur.com/pKopwXp.gif' alt='loading...' />";

// specify the server/url you want to load data from
var url = "http://fiddle.jshell.net/dvb0wpLs/show/";

// on click, load the data dynamically into the #result div
$("#loadbasic").click(function(){
$("#result").html(spinner).load(url);
});

});

If you don't want to use the jQuery library, you can also use plain Javascript. Loading content is slightly more difficult that way. Here is an example of how to do it with javascript only.

To learn more about AJAX, you can take a look at https://www.w3schools.com/xml/ajax_intro.asp

Update the DOM without refreshing the page in React.js

First, let's talk about why putting post in the useEffect dependency causes infinite requests. As stated:

You can tell React to skip applying an effect if certain values haven’t changed between re-renders.

but the problem is that every time you call the effect, you actually change post by calling setPost. this causes a re-render. while react is doing the re-render it checks whether it should run the effect again or not. since the variable post in the useEffect has changed, react decides to run the effect again. this causes the infinite loop.


Back to your main question. If I understood correctly you want to sync your application's state with the server's state regarding posts. You can achieve that by polling or websockets. in polling the client send a request to the server every few seconds to check if there has been any chaneges in the state. websockets make it possible to have a two-way connection between the server and client. the two-way connection makes it possible for the server to send information to the client at any time.

below is a very simple polling solution to your problem. I strongly encourage you to read more about the concept.

// ommited code
const [post, setPost]=useState([])
const url="http://localhost:3000/users"
const WAIT_TIME = 5000;

useEffect(() => {
const id = setInterval(() => {
axios
.get(url)
.then(res=>{
setPost(res.data);
})
.catch(err=>{
console.log(err);
})
}, WAIT_TIME);
return () => clearInterval(id);
}, [post]);
// omitted code

How to render a piece of data stored in an external model without refreshing the page?

Since you're defining you endpoint in the urlpatterns[] as follows:

path('get-employee-name/<int:id>/', views.get_employee_name, name='employee_name'),

the associated view should expect id a second parameter following request; for example:

from django.http import HttpResponse
from django.shortcuts import get_object_or_404

def get_employee_name(request, id):
employee = get_object_or_404(Salesman, id=id)
return HttpResponse(employee.slsmn_name)

In the ajax call, I would rather use an absolute url:

var url = '/get-employee-name/' + employee_number;

(please note the leading backslash) otherwise, the visited url would be relative to the current page;
If the app's urlpatterns in included in the root one with a suffix, add it as required:

var url = '/the_app/get-employee-name/' + employee_number;

Also, you don't need 'data' in the ajax call parameters, since you're expecting the employee_number from the url.

Finally, I would add:

console.log('data: %o', data)

to the success callback to make sure you're receiving what you expect

Fetch random data from API without refreshing the page in react axios

It seems that you are only updating the data in the backend, thus necessitating the "refresh" to refetch the data. Instead of reloading the app you could just refetch the data.

Refactor the two GET requests of in the useEffect hook into a standalone function to be called by the hook and at the end of the form submission.

Example:

const fetchData = () => {
http
.get(baseURL)
.then((response) => {
setData(response.data);
})
.then(
(response) => {},
(err) => {
console.log(err);
}
);
http
.get(
`http://127.0.0.1:8000/api/business_process/get-business-impact/${processId}`
)
.then((response) => {
setDatas(response.data);
})
.then(
(response) => {},
(err) => {
console.log('No Data To Show');
}
)
.catch((err) => {
return false;
});
};

useEffect(() => fetchData(), []);

...

<button
className="color bg p-2 rounded-md w-72"
type="button"
onClick={fetchData}
>
Show
</button>

...

<button
className="color bg p-2 rounded-md"
type="button"
onClick={(e) => {
deleteBusinessImpact(e);
fetchData();
alert('Deleted Successfully');
}}
>
Delete All Data
</button>


Related Topics



Leave a reply



Submit