Json data not rendering to the DOM - javascript

so I'm trying to create a web app that when a user inputs a number from 0 to 50 it renders that quantity of images of dogs. If nothing is imputed it defaults to 3. Right now fetch is retrieving the data but I can't seem to render it. This is the html for it:
<div class="container">
<h1>Dog API: Display Multiple Random Dog Images</h1>
<form action="#" class="js-search-form">
<label for="query"></label>
<input required type="text" class="js-query" value="3"">
<button class="js-submit" type="submit">Search</button>
</form>
<section class="results hidden js-results">
<!--<img class="results-img" alt="placeholder">-->
</section>
</div>
and this is the Javascript for it:
function getDogImages(query) {
fetch(`https://dog.ceo/api/breeds/image/random/${query}`)
.then(response => response.json())
.then(responseJson => {
console.log(responseJson)
return responseJson
})
.then(responseJson => displayResults(responseJson))
.catch(error => alert('Something went wrong. Try again later.'));
}
function displayResults(responseJson) {
return `
<div>
<h2>Here are your dog pictures</h2>
<img src="${responseJson.answers}" class="results-img">
</div>
` ;
}
function displayDogSearchData(data) {
const results = data.items.map((item, index) => displayResults(item));
$('.js-results').html(results);
$('.results').removeClass('hidden');
}
function listenToInput() {
$('.js-search-form').submit(event => {
event.preventDefault();
const queryTarget = $(event.currentTarget).find('.js-query');
const query = queryTarget.val();
queryTarget.val("3")
getDogImages(query, displayDogSearchData);
});
}
$(function() {
console.log('App loaded! Waiting for submit!');
listenToInput();
});
This is the repl.it link if you want to see it https://repl.it/#GianinaSkarlett/DISPLAY-MULTIPLE-RANDOM-DOG-IMAGES-MVP

You're code is fairly close - only a few minor adjustments were needed to get it to work. Consider the code sample below (with documentation) as one option to resolve your issue:
/*
Add displayCallback parameter, which is called to perform
html/dom update on success
*/
function getDogImages(query, displayCallback) {
fetch(`https://dog.ceo/api/breeds/image/random/${query}`)
.then(response => response.json())
.then(responseJson => {
console.log(responseJson)
return responseJson
})
.then(responseJson => displayCallback(responseJson))
.catch(error => alert('Something went wrong. Try again later.'));
}
function displayResults(responseJson) {
/*
Update the code below to insert responseJson directly as image src
*/
return `
<div>
<h2>Here are your dog pictures</h2>
<img src="${responseJson}" class="results-img">
</div>
` ;
}
function displayDogSearchData(data) {
/*
Access message from data, as per API response format
*/
const results = data.message.map((item, index) => displayResults(item));
$('.js-results').html(results);
$('.results').removeClass('hidden');
}
function listenToInput() {
$('.js-search-form').submit(event => {
event.preventDefault();
const queryTarget = $(event.currentTarget).find('.js-query');
const query = queryTarget.val();
queryTarget.val("3")
/*
Add displayDogSearchData as second argument to getDogImages
as per callback above
*/
getDogImages(query, displayDogSearchData);
});
}
$(function() {
console.log('App loaded! Waiting for submit!');
listenToInput();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="container">
<h1>Dog API: Display Multiple Random Dog Images</h1>
<form action="#" class="js-search-form">
<label for="query"></label>
<input required type="text" class="js-query" value="3"">
<button class="js-submit" type="submit">Search</button>
</form>
<section class="results hidden js-results">
<!--<img class="results-img" alt="placeholder">-->
</section>
</div>

Related

How to send data from API to another HTML file

Im using a TMDB API to search for movies and add them to a watchlist.
In this javascript function im getting movie details based on user input and rendering the results to html using bootstrap.
const searchMovie = async (searchInput) => {
try {
axios.get(`https://api.themoviedb.org/3/search/movie?api_key={API_KEY}&language=en-US&query=${searchInput}&page=1&include_adult=false `)
.then((response) => {
console.log(response);
let movies = response.data.results;
let displayMovies = '';
$.each(movies, (index, movie) => {
displayMovies += `
<div class="col-md-3">
<div class="well text-center">
<img src="https://image.tmdb.org/t/p/original${movie.poster_path}">
<h5>${movie.title}</h5>
<h4>${movie.release_date}<h4>
<a class="btn btn-primary" href="#">Add to watchlist</a>
</div>
</div>
`;
});
$('#movies').html(displayMovies);
})
}catch(error) {
console.log(error)
}
}
I have another html file called watchlist.html that i want to send the movie selected from the search results to that file and build a watchlist.
Please try this one before stringify
var obj = JSON.parse(movie);
localStorage.setItem('selectedMovie', JSON.stringify(obj));

Post from React to Ruby (not rails)

I have created a Twitter clone using Ruby in the backend and React in the front end. I have managed to fetch all tweets and I am trying to post a tweet. It is connected but it is posting nothing. Literally an empty tweet.
Below is the React code.
const TweetsFeed = () => {
const [tweet, setTweet] = useState("");
const tweetChangeHandler = (event) => {
event.preventDefault();
setTweet(event.target.value);
};
const postTweet = async () => {
const postRequest = {
method: "POST",
params: tweet,
};
fetch("http://127.0.0.1:9292/tweets", postRequest).then((response) =>
response.json().then((data) => {
console.log(data);
})
);
fetchTweets();
};
Below is the Ruby route and create method code
post '/tweets' do
Tweet.create(tweet: params[:tweet])
end
def self.create(tweet:)
result = DatabaseConnection.query("INSERT INTO tweets (tweet) VALUES ('#{tweet}') RETURNING id, tweet;")
Tweet.new(
id: result[0][0],
tweet: result[0][1]
)
end
Below is the form
<form className="new-tweet-form" action="/tweets" method="post">
<div className="pp-input">
<img src="./images/pp1.jpg" alt="" />
<input
type="text"
name="tweet"
placeholder="What's happening?"
onChange={tweetChangeHandler}
/>
</div>
<div className="extras-button">
<Extras />
<Button type="button" onClick={postTweet}>
Tweet
</Button>
</div>
</form>
It does post to the database, but an empty tweet everytime.

How to post from array mutiple request with axios in vuejs?

i try to post with axios from an array to an api php file and get the responses one by one not just one request. I read something about axios.all() but can't figure it out i am new to javascript.
<div id="app">
<center>
<div id="area">
<textarea v-model="sent" name="sent" id="sent" cols="30" rows="10" class="form-control">
</textarea>
<br>
<button v-on:click="insert" class="btn btn-default">Send</button>
</div>
<div id="good" v-for="message of messages">
<span><h2>Good</h2></span>
{{ message }}
</div>
</center>
</div>
And here is the vuejs code.
<script>
new Vue({
el:'#app',
data:{
sent:[],
messages:[]
},
methods:{
insert:function (){
const vm = this;
splitz.forEach(function(entry){
axios.post('/one.php', {
sent: vm.entry
}).then(response => {
vm.messages.push(response.data.onefinal) ;
console.log(response.data);
}
).catch(function(error){ console.log(error); });
}
}
},
computed:{
splitz: function () {
return this.sent.split('\n')
}
}
});
</script>
You can do it this way:
// Create an array of post requests from splitz array
var requests = splitz.map(entry => axios.post('/one.php', { sent: this.entry }))
// Send all requests using axios.all
axios.all(requests)
.then(results => results.map(response => response.data.onefinal))
.then(newMessages => {
console.log('New Messages:', newMessages)
this.messages.push.apply(this.messages, newMessages)
})
Edit: to send the requests one by one:
insert: function() {
var vm = this;
function sendRequest(arr, i) {
var entry = arr[i];
axios.post('/one.php', { sent: entry }).then(function (response) {
vm.messages.push(response.data.onefinal);
if (i < arr.length - 1) {
sendRequest(arr, ++i);
}
})
.catch(function (error) {
console.log(error);
});
}
sendRequest(this.splitz, 0);
}

Implementing search in js

I've been trying to implement some searching features. I need the program to read search area and redirect the user to the page with results. Here's my search.ejs
<script>
function executeSearch($this) {
console.log('button clicked');
let request_data = document.getElementById('search-area').value;
console.log("Request data : " + request_data);
$.post("search", {subtitle: request_data}, function(json) {
console.log('requested access completed');
})
}
</script>
<input id="search-area" type="search" value="" placeholder="Enter movie title" />
<button onclick="executeSearch(this)" class="details-button">Search</button>
<ul class="search-list">
<% for(let i=0; i< movieList.length; i++) { %>
<li class="single-search-result">
<h3 class="text-light">
<%=movieList[i].title%>
</h3>
<br>
</li>
<% } %>
</ul>
Here's the code handling the request :
app.post('/search', (req, res) => {
movie_controller.getBySubTitle(req.body.subtitle)
.then(result => {
res.render('search', {
movieList: result
});
})
.catch(err => {
console.log(err);
res.render(500);
})});
By using console.log, I've determined that there are no issues in transferring required data, however I can't render 'search' page after getting data from getBySubtitle(). Any ideas what can be causing this? Thank you in advance.

How to retrieve data from form using a POST route?

I am trying to retrieve data from a Bootstrap form element, and save it to a PostgresSQL database using Express and Knex. There are no errors when I run the route; however, the data from the form is saved as null. Here is my form element (I'm using React):
render() {
return (
<form>
<div className ="form-group">
<label>Add a Note:</label>
<textarea className="form-control" name="note" rows="5">
</textarea>
</div>
<button onClick={this.handleClick} className="btn btn-primary"
type="submit">Submit</button>
</form>
)
}
Here is my fetch to the POST route:
handleClick(e) {
e.preventDefault()
fetch('/create-note', {
method: 'POST'
})
}
Here is my Express POST route (app.use(bodyParser.json()) is included in this file):
app.post('/create-note', (req, res) => {
postNote(req.body.note)
.then(() => {
res.sendStatus(201)
})
})
Here is the Knex postNote function:
export function postNote(newNote) {
const query = knex
.insert({ note_content: newNote })
.into('notes')
return query
}
Any help would be appreciated!
With POST requests you may have to wait for data body to be ready. Try this
app.post('/create-note', (req, res) => {
var body = '';
request.on('data',function(data) { body += data; });
request.on('end', function(data) {
postNote(body)
.then(() => {
res.sendStatus(201)
})
});
})
try the following in your markup, and forgo using fetch
...
<form method="POST" action="/create-note" enctype='application/json'>
...
</form>
...
or since the default encoding for a form is application/x-www-form-encoded (doc), add the following middleware to your express app..
...
app.use(bodyParser.urlencoded({ extended: true }));
...
also you could try...
...
<button ref="form" onClick={this.handleClick} className="btn btn-primary"
type="submit">Submit</button>
...
along with
handleClick(e) {
e.preventDefault();
const data = new FormData(this.refs.form);
fetch('/create-note', {
method: 'POST',
body: data
})
}
I found a solution and want to post it incase anyone else runs into a similar issue. The problem was I wasn't querying textarea's value correctly, so I was passing an undefined variable to the database to save.
Here's the solution I came up with:
handleSubmit(e) {
const data = new FormData(e.target)
const text = {note: data.get('note')}
fetch('/create-note', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(text)
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className ="form-group">
<label>Add a Note:</label>
<textarea className="form-control" name="note" rows="5">
</textarea>
<button ref="textarea" className="btn btn-primary"
type="submit">Submit</button>
</div>
</form>
)
}
I put a onSubmit event listener on the form, and created a new FormData instance with the form. Then I created an object containing the value of the textarea to pass into the fetch call.

Categories