Wordpress React Blog Not rendering Images Properly - wordpress

I am new in React. I am attempting to make a live feed from my wordpress site. I am having trouble rendering the images associated with each article.
In the code below I log the mediaSRC variable which I am storing the url of the image. When logging this the proper URL outputs to console. However when I try to create my Post object later on after the if statement, the mediaID is = to "NO IMAGE"
When I am rendering the POST the html img is showing img src="NO IMAGE"
<div className="main-feed">
{posts.map(function(post){
//mediaSRC is eventually going to by my <img src >
var mediaSRC ="NO IMAGE";
//post.featured_media will access the media ID of the image
var media = post.featured_media;
// if there is no image set mediaSRC to this string
if (post.featured_media ==0){
mediaSRC="MEDIA ID IS ZERO";
}
// if there is an image, set mediaSRC to the url of image
else{
j.ajax(React_Theme_Resource.url + "/wp-json/wp/v2/media/" +media)
.done(function(data){mediaSRC = data.guid.rendered; console.log(mediaSRC)})
.fail(function(){console.log("FAIL")})
.always(function(){})
}
//Create Post object NOTE : working without images
return <Post post={post} mediaID={mediaSRC} key={post.id} />
})}
</div>

You are getting your image via an ajax request, but the component is not updated with the new image source. There are a couple of issues here.
It is a bad practice to make ajax request in your render method. The best place for them (if you are not using Flux, Redux or other state management library) is in the constructor.
Secondly, you need to use .setState() (again, if you are using react state to manage the state of the component and the app) method to add the new image source to the component.
You can read more about react state here: https://facebook.github.io/react/docs/state-and-lifecycle.html

Related

How to implement isLoading logic in React right?

The fetching is not going smoothly. I want images to show up at the same time. Here is how I have done it:
const [isLoading, setIsLoading] = useState(false)
useEffect(()=>{
setIsLoading(true)
fetch(url).then(res=>res.json()).then(data=>{
setPhoto(data)
setIsLoading(false)
})
},[url])
And then, I check, if isLoading is true, then I return "Loading" text. Else, the code should return the images page:
return (
<div className="App">
<header>.....
{isLoading?<p className={'text-5xl mt-11'}>Loading...</p>:<div className={'flex flex-wrap space-x-2 justify-around '}>
{photos?photos.hits.map((photo, index)=>{
return <img className={'m-5 h-80 rounded-2xl'} onClick={handleClickOnPicture} key={photo.webformatURL} src={photo.webformatURL}/>
}):""}
Your images loading actually happens in 2 steps:
You fetch your image URL's (data stored in photo state), for which you properly handle isLoading state
You display the <img> elements with src attribute populated with URL's from step 1; but this is only the point where the browser knows of these new media resources, and starts fetching their content: this explains why you see your images appearing 1 by 1; the <img> element is there, but its actual content is still being fetched
To force the browser fetching your images content before you display them, the classic solution is to create an Image (HTMLImageElement) and to populate their src attribute. The browser starts requesting their content even if these objects are not actually inserted into the DOM.
Then you need to know when these images have finished loading in the background. For that, we use the onload property on the <img>, which adds an event listener that is called when the content has been retrieved (and cached) by the browser.
Once all images have finished loading, we can insert them into the DOM (possibly through new <img> elements, provided that they re-use the same URL's), and the browser will use its cached data to display them "instantly".
See e.g. How to preload images in React.js? for how to implement step 2 in details with React.

How do I style a NodeJS response with CSS?

I got this code for a weather app that I am building in NodeJS. when I receive the response from the nodejs I receive the details(temperature, rain) in plain text. So I cannot style it. is there any method I can use to get the response as a styled site with CSS? I cannot use a prebuilt html code cause the weather is always changing. Is there a mthod to get a styled site?
app.post('/', function(req,res){
const query=req.body.cityName;
const apiKey=' '
const url="https://api.openweathermap.org/data/2.5/weather?units=metric&q="+query+"&appid="+apiKey;
https.get(url,function(response){
console.log(response.statusCode);
response.on("data",function(data){
const weatherData = JSON.parse(data);
console.log(weatherData);
try{
const temp = weatherData.main.temp;
console.log(temp);
const weatherWescription = weatherData.weather[0].description;
console.log(weatherWescription)
const icon =weatherData.weather[0].icon;
const iconUrl="http://openweathermap.org/img/wn/"+icon+"#2x.png"
res.write("<h1> The Weather is currently " + weatherWescription + "</h1>");
res.write("<h1> Temperature is "+temp+"</h1>");
res.write("<img src="+iconUrl+">")
res.send();
}
catch(e){
res.send("Enter a Valid City Name")
}
});
});
});
Here are some of the options you have:
Your API can fetch JSON data (no HTML) and then you programmatically insert that into your page with Javascript in the web page by inserting that data into the already styled page to replace the data that is already there. This should then inherit the styling that you already have, using the existing CSS rules. If you have a client-side template system such as EJS, you could use that to generate HTML from a template stored in your page with the new data inserted into the template and then insert that generated HTML into the page. Or, you can insert the data manually into the existing HTML with your own Javascript.
Your API can fetch a piece of styled HTML that uses CSS classes and ids that will inherit the existing CSS rules already in the page. You then use client-side Javascript to insert this piece of styled HTML into your existing page and it will automatically be able to use the CSS rules already in the page.
Your API can fetch a whole new HTML body which can then insert. You can either include CSS rules in the new HTML body or you can use the existing CSS rules from the page.
Hi #Pasindu sathsara,
My understanding - you are asking for a css style change respective to response( correct me if i am deviated)
The idea is like,
Understand the api response.
Write N number of style tag w.r.t climate and keep it as node string
Have a simple switch and compare climate and get the climate
According to climate res.write(css style tag in variable ) before res.end() so that style is dynamic according to response
Regards,
Muhamed

meteor - live code update to webpage?

I'm curious to know whether Meteor would be suitable for following, and how I would go about writing the code.
I'd like to create a webpage, where by the code in a specific "div" can be hotswapped on the fly to users currently looking at that page. (eg. the div contains some text, but then an image replaces it.) Ideally, the swap would be executed manually by the the webpage's admin through the click of a button, or some code fired off on the server or something. Regular viewers to the webpage would not be able to do this - they only see the live changes on the page.
real-life example:
live internet broadcast is off-air, therefore the "div" contains "off-air" text. live hotswap of code happens when broadcast goes on-air, and the viewers of the webpage now see the html5 broadcast player in the "div" instead. later it is swapped back once the broadcast goes off-air.
I'm completely new to the Meteor platform, so I consider myself a newbie :) Any help is appreciated.
You might better off by using a reactive div using data from a collection (I'm going to use an example with raw HTML but you might be better off implementing your own functionality with what content to display instead: i.e
Basically take advantage of reactivity over hot code swaps
Client side html code
<template name="home">
<div>
{{{content}}}
</div>
</template>
js code
if(Meteor.isClient) {
MyCollection = new Meteor.Collection("MyCollection")
Template.home.content = function() {
if(MyCollection.findOne()) {
return MyCollection.findOne().content
}
}
}
if(Meteor.isServer) {
MyCollection = new Meteor.Collection("MyCollection")
//Set an initial content if there is nothing in the database
Meteor.startup(function() {
if(!MyCollection.findOne()) {
MyCollection.insert({content:"<h1>Test content</h1><p>Test Data</p>"
}
}
//A method to update the content when you want to
Meteor.methods({
'updatecontent':function(newcontent) {
id = MyCollection.findOne()._id
MyCollection.update(id, {$set:{content:newcontent}});
return "Done"
}
}
You can update your content either in the mongo collection or with something like (in your web console, client side or server side javascript):
Meteor.call("updatecontent","New content",function(err,result) {
if(!err) {
console.log(result)
}
});
Which will update the code live when you use it.
I'm sorry it's quite long but the bulk of it is setting/updating the html. Its actually much nicer than a hot code swap which would refresh the user's page

Knockout JS image binding

I am using knockout js in my single page application. I have a file upload input tag that I'm using knockout to upload the file with. In this case the files being uploaded are images.
Once the image has been processed by my ASP.NET Web API, and it comes back into my callback function I am inserting the response into an observable array which inhand updates the screen with the new image and text that was added.
However, for some reason the images aren't being displayed. If I refresh the page it loads the images fine but when adding to the observable array it's not showing the images.
Any ideas?
Edit: Here is my code that adds the item, it's pretty straight forward.
item = {
"insightTypeId": 0,
"memberId": currentMemberId(),
"postedByMemberId": store.fetch("currentUser"),
"value": insight(),
"image": "content/insights/" + fileName
};
messaging.client.addItem = function(item) {
member().insights.unshift(item);
};
Update
Forgot to mention that it works fine on a computer viewing the site, but on a phone it doesn't work.
I figured out that it was a mobile safari resource issue

Pre-Select Images when opening WordPress 3.5 media manager

I've been playing around with the new media manager in WordPress and had some fun with it, but have reached the point where I'm banging my head against a wall.
I have a custom meta box that I'd like to store some images in (well it's a hidden input and I'm currently storing their ID's, but could equally be the image objects), then making an AJAX call to show some thumbnails, which I have subsequently made draggable so users can reorder (not necessarily relevant just some background).
My problem is that when I open the media manager, no images are selected, so if a user wants to edit the pictures in their gallery they need to select them all again.
What I'm trying to figure out, is how do I open the media manager with the current images passed through so they are pre-selected.
So, broadly, my code looks like this
jQuery('#myButton').click(function(e) {
e.preventDefault();
frame = wp.media({
title : 'My Gallery Title',
multiple : true,
library : { type : 'image'},
button : { text : 'Insert' },
});
frame.on('close',function() {
// get selections and save to hidden input plus other AJAX stuff etc.
}
frame.open();
});
My thought is that there must be either a parameter to pass into the frame (probably a JSON object of the images, or I need to create an event for
frame.on('open', function() {
// Set selected images
}
But I have tried both ways round and am not getting anywhere.
It would appear possible, as changing the 'Featured Image' takes you to the library with the current one selected - I've just been unable to understand the core code sufficiently yet and hope someone else has !
After studying the core for a bit, the answer here is really quite straightforward.
Listen for the open event of the wp.media object, grab the state, create attachment objects with your id's and add them to the selection.
frame.on('open',function() {
var selection = frame.state().get('selection');
var ids_value = jQuery('#my_field_id').val();
if(ids_value.length > 0) {
var ids = ids_value.split(',');
ids.forEach(function(id) {
attachment = wp.media.attachment(id);
attachment.fetch();
selection.add(attachment ? [attachment] : []);
});
}
});
This works when selecting multiple images as well as single and assumes that using the code above you have stored the values in a single text/hidden field with comma separation.
not a real answer, but somethings that I have noticed
using your code the frame.open( console.log('open') ) does trigger the console.log.
The other frame.on('open', function() { console.log('on->open')}) does not.
When looking at the post edit page. (Where a featured image is already set).
If you open the featured img window a few things happen that are interesting.
WP does 3 ajax calls, the 1st and 3rst contain the featured img id. the 2nd is the same as with your code.
when the popup is loaded the featured image is visible / loaded before the rest of the images. When those show up the featured image is put in the right order.
When looking in firebug at the dom tab I discovered that the var wp.media.model.settings.post.featuredImageId holds (wait for it) the featured image value.
Hopes this helps you in some way.
I think those guy manage to do it :
https://wordpress.stackexchange.com/questions/76125/change-the-default-view-of-media-library-in-3-5/76213#76213
But this doesn't work for me.
I ve got the jquery in the footer of my post/edit, post/new but that just don't work for me :(

Resources