I'm trying to load a bunch of png images that are in a folder in my project. I'm using a function that takes in an array of strings that signify the name of the actual images.
The actual html that comes up in the console seems correct, however the images don't get loaded. The weird thing is, if I hard code in the html with the src of one of the images, the src in the inspector comes up as 'name.93439.png' with random numbers in between the name and the file extension, and the image shows up. But the source I am injecting in the javascript using template strings is no different than what I am putting into the html when I hard code it.
So is there something I'm missing here with loading images? Why does hard coding it in work, but when I try using JS it doesn't give the same results? Code below:
FILE STRUCTURE:
index.html
/src
index.js
/assets
/images
...{all of the images}.png
function loadImages(names) {
names.forEach((name) => {
let image = document.createElement('img');
image.src = `src/assets/images/${name}.png`;
let newDiv = document.createElement('div');
newDiv.appendChild(image);
document.getElementById('images').appendChild(newDiv);
});
}
This happens because parcel hashes your assets during building. When executing the js, ${name} is not aware of the (parcel) hash and therefore doesn't finds the correct file. Try to take out the assets from the build process and copy them to your dist folder (you'll probably want to automate this at some point). So the assets file names do not get hashed.
Related
I have a project structure with two separate folders, one for the backend and the other one for the frontend.
I'm trying to generate PDFs with an image inside comming from the public file of the frontend.
I'm getting it with my actual image path put into a require('').
getImagesRequire(state) {
state.images.forEach( el => {
el.src = require(`#/assets/${el.dir}`)
})
return state.images;
}
It's working perfectly for all images in that list but one, when that original path is sent through the require('') it's returning the base64 code of the image, and I don't understand where it's coming from. I'm thinking maybe it comes from the file but it's png like every other image file... Any insight welcome
https://codesandbox.io/s/optimistic-sammet-1yms2?file=/public/index.html
This is my minimal reproducible example.
When the page was only static html with javascript the sounds were working. After refactoring into a React app the sounds have stopped working and I get 2 errors: Uncaught Error: The error you provided does not contain a stack trace. and (index):1 Uncaught (in promise) DOMException: Failed to load because no supported source was found.
When I paste the HTML file path into the browser the sounds are working, but when I run the app on localhost there are errors and no sounds. The rest of the javascript is working, and I have made sure the file path for the sounds is correct.
This is my directory layout.
This code is from daily-planner/public/planner.js and shows the audio play functions:
var penNoises = ["../src/sounds/Pen1.wav", "../src/sounds/Pen2.wav"];
var randomPen = Math.floor(Math.random() * penNoises.length);
function penSound() {
var audio = new Audio(
penNoises[Math.floor(Math.random() * penNoises.length)]
);
audio.volume = 0.1;
audio.play();
}
function penCross() {
var audio = new Audio("../src/sounds/penCross1.wav");
audio.play();
}
The event listeners that call these functions are attached to <li>'s that are dynamically generated from an array, not <audio> elements.
The reason why this doesn't work is the way React compiles the files.
All that is on the src folder, is packed up in a folder named 'static'.
And every file in there is properly linked to the index.html file.
(and I mean, linked as we would expect from the un-compiled project).
It is recommended to load assets on src.
But links on the public folder remain intact, they do not follow the re-arrangment in directories done by the compilation. Run npm run build or npm start to check out.
So the path on your planner.js contains a URL - that's expected - but is pointing nowhere.
That being said/sad, what is logic in the raw project, may not be what is compiled. To be better off maybe look at these rules.
Basically, planner and .wav would be better placed in the source folder. You can also move the .wav file in the public folder (not best option).
I've fixed your codesandbox with that second approach. In part, because it's not easy to deduce from the post if you really need that planner.js in public or not.
Anyways, Hope this helps.
You can just put the audio file inside of the public folder since the script using it is inside public.
function playSound() {
var audio = new Audio("./penCross1.wav");
audio.play();
}
Alternatively, you can put planner.js inside src so you can access the wav file residing inside src
So I have created a small app using node.js and have served my assets folder like so
app.use(express.static('assets'));
Now in my .ejs file I can reference an image easily, e.g.
var img = document.createElement('img');
img.src = '/img/picture.jpg'
Now, what I want to do is loop through all the images in that folder and display them on the page.
Something like
var images = new Array();
images = { All pictures in the /img directory }
images.forEach(function(image) {
var img = document.createElement('img');
img.src = image;
}
So my question is, how do I get the names of all the static images using JS? Do I instead have to make an AJAX call to the directory to read the file names? Or do this server-side with node.js and pass the images through to the .ejs file. Typically, which is better practice (can be a separate question but I thought I would ask)?
Thanks in advance
So my question is, how do I get the names of all the static images using JS?
The client knows nothing about what URLs the server will respond to until it makes a request to them.
Do I instead have to make an AJAX call to the directory to read the file names?
That would be one possible approach.
Or do this server-side with node.js and pass the images through to the .ejs file.
That would also work
Typically, which is better practice (can be a separate question but I thought I would ask)?
It depends.
Using Ajax would require a second HTTP request, but the response could be cached.
Doing it when the page loads would reduce the number of requests but on, but the work to get the list would have to be done every time the page loads and would increase the size of that page.
So which is best, using the only measurable metrics, depends on how often an individual is going to reload the page and how often the list changes.
I have an ng-repeat that, among other thing, outputs on image:
<div class="installation" get-products install-index="{{$index}}" ng-repeat="installation in installations track by $index">
...
<img ng-src="{{installation.logo}}" />
...
</div>
When my app starts it downloads needed images and stores their location in a local database. When the page is viewed the installations are populated:
<div class="installation ng-scope" ng-repeat="installation in installations track by $index" install-index="43" get-products="">
...
<img src="C:/Users/.../AppData/Local/Packages/.../LocalState/installations/.../...png" ng-src="C:/Users/.../AppData/Local/Packages/.../LocalState/installations/.../...png">
...
</div>
(dots used to hide person and client data)
If I paste the src location into my browser I see the image so I know it's saved at that location. However, in my app it's not showing. This is a constant issue through the app with the downloaded files. I know the image are in the correct area and the src location is correct but none of them show.
--- EDIT ---
I do have white listing applied as I was getting an unsafe for file:///. Also, when I was using a relative path it was working fine. I had a preloaded database that pointed to file inside the app files.
I don't think it's an access issue since I have a .db file at the same location that all my data is being pulled from.
--- EDIT ---
I set it as file:///C:/... and I'm having the same issue.
I also tried file:///C:/... , http://localhost/..., http://localhost:/..., http://localhost:C/..., C:/..., and file:///.... None of witch give me anything. The first two localhost items do give me a broken image icon, that's about it. I'm not running a local server, just thought I'd try it.
You can do this in two different ways:
1) Use the file protocol
2) use a local host server to store the picture and access it from the local host
for security reasons you cannot use your file system path for images. you shouldn't even use it at all, because when your app gets hosted, you wouldn't be accessing the image via such paths.
method 1:
just add file:/// in place of the c:/. file is the protocol for your file system, just as http or HTTPS is a web protocol.
NB: I haven't tested or used this before so I'm not really certain. I'm posting this from a small mobile device. but I believe it should work.
method 2:
start your wampserver or python server or any local server you have. put the image in a folder where your server can access (if wampserver, this would be a folder or directory in your WWW). say the name of the folder is "my_images" and your wampserver is running on localhost.. you can access the image like so:
http://localhost/my_images/image_name
use this path for your ng-src.
Because I Cordova File and Windows weren't playing nice using the call for cordova.file.dataDirectory didn't work. Instead I used the fs object returned by window.requestFileSystem(...,function(fs){...});
When generating my save to path as well as the path to create directories and location data I used fs.winpath which returned C:/.... The web (which Cordova basically is) won't allow you to have access to local files not associated with the site/apps structure, which is now obvious.
I dug in to the fs object and found fs.root.nativeURL points to ms-appdata:///local/. Switching everything over to this still downloaded all files and directories to the same location but stored that to the database as the file location. When the app loaded the ms-appdata path instead of the C:/ path the images displayed.
oh, a Cordova app.. why don't you place the file in an images folder In your project. since all files will be loaded using index.html (I assume). you can easily refer to the file relative to the location of index.html. how I would normally organize my project is that, my index.html and folders containing resources like js, CSS etc would be on thesame level, so I can easily get the image files using ng-src="img/image_name". so I could have a structure like this
index.HTML
img
..image_name.ext
..image2.ext
css
..style.css test it in a browser location if it works, it will work on the device. Cordova would know how to translate d into something it can recognise.
This is some sample code, i quickly put together. I tested it and it worked. Firstly i create a directory using file plugin and then download to this directory using file transfer. Replace the url parameter of file transfer with the url you wish to download from.
$ionicPlatform.ready(function() {
$cordovaFile.createDir(cordova.file.externalDataDirectory,
file_location,false).then(
function(success){
return success;
},function(error){
return error;
}).then(function(value){
var url = material.file_uri;
var targetPath = cordova.file.externalDataDirectory
+ "/" +file_location + "/" + file_name;
var trustHosts = true
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
console.log(result)
}, function(err) {
console.log(err)
}, function (progress) {
$timeout(function () {
console.log(Math.floor((progress.loaded / progress.total) * 100));
})
});
})
})
I have a spring based web application MyWebapp built using maven and deployed on Websphere 6.1
The folder structure is:
MyApp --> src ---> main --->
The main folder is further having resources and webapp folders.
webapp folders is having other folders like images, theme, jscript, JSP, META-INF, WEB-INF
images folder is having icons folder with say example.png
So fetching example.png on localhost as:
http://localhost:9080/MyWebapp/images/icons/example.png
succeeds.
In jscript folder I have a sample.js javascript file where some functions are defined.
I am importing this javascript file in JSP pages as:
<script src="<%=request.getContextPath()%>/jscript/sample.js" type="text/javascript" language="Javascript"></script>
This javascript file is having a function which tries to fetch image as below:
iconFile = '../images/icons/search_result.png';
anchor.style.backgroundImage = 'url(' + iconFile + ')';
anchor.style.backgroundRepeat = 'no-repeat';
anchor.style.backgroundPosition = '1px 2px';
anchor.className = 'toplevel-tab';
The complete function basically tries to place a icon before some text in JSP.
The code gets parsed. However, the image does not get displayed.
Running the code independently on a simple html with the png images in the same folder as html and javascript files succeeds. Here i will just have iconFile = "search_result.png"
So, it is not code issue.
Issue is that the image is not getting located or the server is unable to find the image in above javascript code.
What am I doing wrong ?
How can I solve it ?
The answer for https://stackoverflow.com/a/8298652/887235 which I accepted earlier does not work.
So please do not downvote this question as a duplicate one.
Also I am working on restricted environment where access to programs like Tail will not work.
Changing
iconFile = '../images/icons/search_result.png';
to
iconFile = '/images/icons/search_result.png';
also does not work!!
Thanks for reading!
You just have to understand how relative paths work. Even if the path is in a JavaScript file, the path is not relative to the location of this JS file, but it's relative to the URL of the HTML page being displayed in the browser.
So, if the URL of the page executing this javascript code is
http://foo.bar.com/myWebApp/zim/boom/tchak.html
and the URL of the image is
../images/icons/search_result.png
The absolute URL of the image will be
http://foo.bar.com/myWebApp/zim/boom/../images/icons/search_result.png
which is the same as
http://foo.bar.com/myWebApp/zim/images/icons/search_result.png
An absolute path like /images/icons/search_result.png is also resolved from the root of the web server, and not the root of the webapp (the browser doesn't know what a Java webapp is and doesn't care). So it's resolved as
http://foo.bar.com/images/icons/search_result.png
You would need to prepend the context path to the path to make it really absolute:
<%=request.getContextPath()%>/images/icons/search_result.png
or, without scriptlets:
${pageContext.request.contextPath}/images/icons/search_result.png
You need to give your javascript an awareness of the path to the root of your application, as this will change on context. Start by declaring a global variable, such as:
<script>
var siteroot = "<%=request.getContextPath()%>";
</script>
Then, you are ready to use it later, such as:
iconFile = siteroot + '/images/icons/search_result.png';