How to display image from mongodb using Reactjs - mongodb

I've saved my image in Mongodb like that :
"img": {
"data": "<Binary Data>",
"contentType": "image/png"
}
I try to display it in ReactJS using this code :
..{products.map(product => {
<img src= {product.img} />
But nothing is displayed. Any idea please to fix it.

You are trying to display your image in src attribute with binary data when it expect an url.
If it's binary data you need to diplay it like this and tell to your component that you are passing binary data
<img src={`data:image/png;base64,${product.img.data}`} />

Related

Ionic 5 Directory tree dynamically

I have done a simple JavaScript file browser which shows the contents of each directory, loading the subdirectory contents from the backend using an AJAX request when the directory name is clicked. Loading the full tree is out of the question. The directory contents are sent in JSON. The directory is something like the one below and cannot be loaded as a whole recursively due to the number of directories and files. The (imaginary) directory structure is simple, but it can have several nested levels:
docs
assemblies
2019-07
doc-6811.txt
instructions-6811.pdf
2019-08
doc-7012.txt
instructions-7012.pdf
...
invoices
2019-07
invoice-6811.pdf
2019-0
invoice-7012.pdf
tickets
2019-07
ticket-98141.txt
The items for each directory are in an array of JS Objects:
[{
name: '2019-07',
isDirectory: true,
fullPath: "/mnt/samba/docs/assemblies/2019-07"
},
{
name: '2019-08',
isDirectory: true,
fullPath: "/mnt/samba/docs/assemblies/2019-08"
} ...
]
There are files as well, of course, but they are not a problem. Now I need to do the same in Ionic but, I am totally lost with the starting point. The top directory renders nicely and the current simple template (I call it a template) is something like this:
<ion-content>
<ion-list>
<ion-item-sliding *ngFor="let d of directories">
<ion-item (click)="openFolder(d)"> <!-- just an example call --->
<ion-icon name="folder" slot="start" *ngIf="d.isdirectory"></ion-icon>
<ion-icon name="triangle" slot="start" *ngIf="!d.isdirectory"></ion-icon>
<ion-label text-wrap>
{{ d.name }}
<p>{{ d.fullPath }}</p>
</ion-label>
<!-- THIS is where the directory contents should appear using
the same structure as this template -->
</ion-item>
</ion-item-sliding>
</ion-list>
</ion-content>
What the code should do is simply fetch the data from the backend and bind it to an array variable, which would then be rendered below to the spot given above. Can this be done in Angular, or is using some other framework any easier? I assume there is a component approach of some sort available, but it should be totally dynamic and fetching plus rendering of one directory should take place per request.
Fetching the directories is a simple task and I get the array just fine. However, I have not been able to get any rendering done yet. Any alternatives and/or pointers are welcome.
Your JSON has to be a recursive JSON. By that I mean,
{ "items": [
{
"name": "ABC1",
"isDirectory": true,
"fullPath": "/mnt/samba/docs/assemblies/2019-07",
"children":[
{
"name": "ABC11",
"isDirectory": true,
"fullPath": "/mnt/samba/docs/assemblies/2019-08"
},
{
"name": "ABC12",
"isDirectory": true,
"fullPath": "/mnt/samba/docs/assemblies/2019-08"
}
]
},
{
"name": "ABC2",
"isDirectory": true,
"fullPath": "/mnt/samba/docs/assemblies/2019-08"
}
]
}
If it can be this way, you can handle the same using recursive ng-template
A sample of the same is as given in this link.
Click here to view the link.
A little Google on recursive ng-template can also help. :)
I sincerely hope that this helps.

Search results link tabs

I'm building a search application and am trying to get some results links that appear in tab format to work. Much like you see on google.com/search=?user_query and bing.com/search=?user_query... where after you submit the initial query, you can click on "Images", "Shopping" and "News" for example and a different results view is rendered based on the the result link/tab that you clicked.
I'm using ReactiveSearch to build my search UI. So far I have this:
ResultNavigationTabs.tsx to build the link tabs
class ResultNavigationTabs extends Component {
render() {
const { classes, items, location: { pathname } } = this.props;
return (
<ul className={classes.nav}>
{items.map(item => (
<Link to={item.link} key={item.text}>
<li className={item.link.startsWith(pathname) ? "active" : ""}>
{item.text}
</li>
</Link>
))}
</ul>
);
}
}
export default withStyles(styles)(withRouter(ResultNavigationTabs));
I then render this component in my ResultsViewPage.tsx like so:
render() {
const { selected } = this.state;
...(omitted for brevity)
<ResultNavigationTabs2
className={classes.myNavigationTabs}
items={[
{ text: "Web", link: `/search?q="${selected}"` },
{ text: "News", link: `/news?q="${selected}"` },
{ text: "Shopping", link: `/shopping?q="${selected}"` },
]}
/>
The links do render but they do not work. If I hover over the links, the search query string is empty (http://localhost:3000/search?q=%22%22). If you've worked with ReactiveSearch, it should be: http://localhost:3000/search?q=%22user%20query%22.
I have had it working but only when I render ResultNavigationTabs in the same file as the search box (DataSearch in ReactiveSearch language). However, if I do that it appears right below the search box in the Header instead of the results area.
I need to figure out a way to render ResultNavigationTabs in the ResultsViewPage.tsx file with working links.
After doing some more thoughtful searching, I found the answer right here on SO! Comes complete with 2 CodeSandBox demos as well - check them out.

Fetching dynamic id and url from image with JS

I'm implementing a fancybox into my project and I'm writing a script to automatically wrap an anchor around the images with the url to the image and a "data-fancybox" attribute to let the fancybox script do its thing. However, I'm only getting the url to the very first image, since they all share the same class. There is a dynamic figure id that seems to be the one to get.
My question is - how do I use this figure id to fetch the appropriate img src?
The html is like this:
<figure id="XXXXXXX">
<div>
<img src="image.jpg" />
</div>
</figure>
... other stuff ...
<figure id="YYYYYYY">
<div>
<img src="image2.jpg" alt="">
</div>
</figure>
My code right now is as follows (which works, but only returns the first image url):
$(document).ready(function() {
var src = $("figure img").attr("src");
var a = $("<a/>").attr( { href:src , "data-fancybox":"" } );
$("figure img").wrap(a);
});
I know I can use
var id = $("figure").attr("id");
to get the id I need, but I'm pretty new to coding so I'm not sure how I implement this and use it to get the correct url. Any help is appreciated!
If your goal is to make your images clickable, then you can do smth like this:
$('figure img').each(function() {
$(this).parent().css({cursor: 'pointer'}).attr('data-fancybox', 'gallery').attr('data-src', this.src);
});
DEMO - https://jsfiddle.net/1jznsL7x/
Tip: There is no need to create anchor elements, you can add data-fancybox and data-src attributes to any element and it will work automagically.

Dynamically set fancybox 3 iframe size

When dealing with dynamically sizing the iframe in fancybox, I accidentally found that setting data-width and data-height on the [data-fancybox] is helpful after reading this answer.
Exmaple HTML element:
<a data-fancybox data-width="<?= $banner_width; ?>" data-height="<?= $banner_height; ?>" data-src="example.com" href="javascript:;">example.com</a>
and js:
$("[data-fancybox]").fancybox({
afterLoad: function ( instance, slide ) {
$('body').find('.fancybox-content').css({"width": slide.opts.width + "px", "height": slide.opts.height + "px"});
}
});
What I couldn't figure out is that there is no explanation of data-width and data-height usage on HTML element from fancybox documentation (please correct me if I'm wrong).
NOTE: these two code snippets above do work for me, but they have to work together, it wouldn't work if one of them is taken off.
Can anyone explain that a little bit for me please?
Based on fancybox 3 documentation, they do offer a way to set our own custom options by creating data-options attribute. Here is the example from the documentation:
<a data-fancybox
data-options='{"caption" : "My caption", "src : "iframe.html"}' href="javascript:;">
Open external page using iframe
</a>
You can see the value of these options by console.info( slide.opts ) from the callback function like onComplete (slide is one argument in the callback function ).
Not surprisingly, these two snippets are the same:
<a data-fancybox data-width="<?= $banner_width; ?>" data-height="<?= $banner_height; ?>" data-src="example.com" href="javascript:;">example.com</a>
<a data-fancybox data-options='{"width" : "<?= $banner_width; ?>", "height" : data-height="<?= $banner_height; ?>", "src" : "example.com" }' href="javascript:;">example.com</a>
So, in my javascript, I use slide.opts.width to get the value from data-width and slide.opts.heightto get the height from data-height, that is how my width and height value get passed from backend to frontend.
Since these two values are processed in afterLoad callback, so every iframe will be initiated with different width and height.
Properties - data-width and data-height - are used to tell the script real dimension of the image. The script then can calculate position and start zooming thumbnail while real image is still loading.
See documentation - http://fancyapps.com/fancybox/3/docs/#images
These properties are not used anywhere else.
You can use { iframe : { css : { width: '', height : '' } } } to set iframe element width/height, but there is no option to change iframe content.

Polymer REST backend

I have a backend written in golang exposing /api/list interface. It returns lists when called from GET and create new list when it receive POST with parameters.
I can read it with standard core-ajax element, there is a huge amount of examples to do that.
What I didn't understood is what should I do, when I want to create new element through POST? I read the documentation and searched for sample code for half day, can you point me to right direction?
//
Ok, thanks for help, it was really only bad format of json I was sending. There is still dark cloud in my mind telling that I misunderstood something from conceptual view. Is this:
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-ajax/core-ajax.html">
<polymer-element name="channels-service" attributes="channels">
<template>
<style>
:host {
display: none;
}
</style>
<core-ajax id="ch_load"
auto
url="/api/list"
on-core-response="{{channelsLoaded}}"
handleAs="json">
</core-ajax>
<core-ajax id="ch_update"
url="/api/list"
on-core-response="{{channelsUpdated}}"
method="POST"
handleAs="json">
</core-ajax>
</template>
<script>
Polymer('channels-service', {
created: function() {
this.channels = [];
},
channelsLoaded: function() {
// Make a copy of the loaded data
this.channels = this.$.ch_load.response.slice(0);
},
newChannel: function(ch_name) {
// this.$.ch_update.body = "ch_name";
this.$.ch_update.body = '{"Name":"pitchalist2"}'
this.$.ch_update.go();
},
channelsUpdated: function() {
//window.log(this.$.ch_update.response.slice(0));
}
});
</script>
</polymer-element>
correctly written data layer? It looks very counterintuitive to me and in examples using local data storage it works way easier.
You can send a POST request by setting the method attribute (method="POST") and the body attribute (body='{"my":"data"}'). Indeed you need a second iron-ajax element for this request.
See the attributes section in the iron-ajax documentation.