Best JS-Framework for Asynchronous Image Gallery Loading with MongoDB - reactjs

So, over the past week I have looked at loading multiple galleries at once. I have been working in MeteorJS with blaze templates but, the methods I am using aren't working.
Essentially, all my data comes from multiple MongoDB collections which are organized in one main collection. When the website starts, I want to access the list of current collections and for each collection display a gallery of photos.
(Main Photo Page)
{{#each collections}}
{{>gallery collectionName=collectionName}}
{{/each}}
(Gallery Template)
<Template name="gallery">
{{getPhotos}}
</Template>
I have tried using a reusable blaze template that is fed the data and then runs a helper to display the images. It works, but I am having trouble loading only one template/collection at a time. I want to load one first, when that is done, load the next etc.
I have also wondered about using ReactJS for this with MeteorJS on the backend, but before I start, I'm wondering about how easy is it to load components one by one vs templates?
Thanks for any ideas or help!

You could try merging the cursors in a helper, instead of inside the template. This will force the order you like and still be reactive since the find is in a reactive context (the helper).
(HTML)
<Template name="gallery">
{{#each getPhotos}}
<img src="{{this.src}}">
{{/each}}
</Template>
(js)
'getPhotos':function(){
let mergedCursor = [];
for (collectionObject in Template.currentData().collections){
//not clear how you are getting the collections
mergedCursor.concat(collectionObject.find().fetch());
}
return mergedCursor;
}
You could also import the collections in the same js file and merge them directly.

Related

convert angular view to static html

I hvae an angular view of a pdf preview that utilizes a controller to fill the view in. I am using pdflayer then to convert the html page into a pdf. The problem however is that no matter how I try and do this the scope variable values never make it into the pdf. I am basically trying to figure out a way to capture the angular view as an html string (data already injected) so that I can pass it to pdflayer. I have tried creating a directive and used replace within the directive then collecting the DOM as a string using .HTML().
For example:
I could like this
<div id="name">{{test.name}}</div>
to become this
<div id="name">Bob Smith</div>
It inevitably however turns into this when i use $('#name').html() and then console log it
<div id="name"></div>
or
<div id="name">{{test.name}}</div>
Any help would be appreciated even if the solution is to use a different method to create the pdf. Ultimately, I need to get a angular view into a formated pdf.
Please check if below library would work for you : https://www.npmjs.com/package/angular-save-html-to-pdf

Show multiple pages of PDF with Angular and pdf.js

I want to show PDFs in my angular application. It should be possible to show multiple pages at once and to search inside the PDF.
I tried angularjs-pdf to do so, but it lacks these features. Is there a angular wrapper for pdf.js that can do this? Or can somebody get me startet on how to implement pdf.js in my angular application without a wrapper?
Assuming this statement:
"I want to show PDFs in my angular application"
Anyone searching for this, could ought to check out ng2-pdf-viewer, for more information on this module, can check this out ng2-pdf-viewer PdfShowcase
Basically, this module could somewhat allow one to display more than one PDF in a single screen.
app.component.ts
// Declare the pdf as an empty array
pdfs = [];
// Assuming requesting PDFs from server through MVC style
getPdfs(){
this.getPdfService.getPdfs().subscribe(response => {
response.body.forEach((value, index) => {
this.pdfs.push({
id: index,
obj: window.URL.createObjectURL(value);
});
});
});
}
app.component.html
<div *ngFor="let pdf of pdfs, index as i;">
<div *ngIf="pdf[i]">
<pdf-viewer
[rotation]="0"
[original-size]="true"
[show-all]="true"
[fit-to-page]="true"
[zoom]="0"
[zoom-scale]="'page-width'"
[stick-to-page]="true"
[render-text]="false"
[external-link-target]="'blank'"
[autoresize]="true"
[show-borders]="true"
[src]="pdf.obj"
(after-load-complete)="onPdfComplete($event)"
(error)="onPdfError($event)"
style="width: 100%; height: 800px;">
</pdf-viewer>
</div>
</div>
If this library is not suitable for your use case, you may try with other libraries which uses iframe or similar strategy. Refer here is a useful source worth checking it out.
I know I'm a little bit late for this post but thought of posting here might help some folks who is looking for the same thing. Hope it helps.
From ng2-pdf viewer page, it recommends your desire "angular wrapper for pdf.js", There are a ton of built in functionality Mozilla's viewer supports; such as print, download, bookmark, fullscreen, open file, zoom, search,......
If you need to display multiple PDF files simultaneously and if you don't mind using iFrames, I recommend ng2-pdfjs-viewer. https://www.npmjs.com/package/ng2-pdfjs-viewer

React : best way to inject Component in dynamically loaded HTML?

I'm new on React (I more at ease w/ jQuery or AngularJS). I have a special case and I don't find a good way to resolve it...
My app contains an area which is like a "document viewer". It loads an HTML content from the backend (via API, using Fetch) and inject it in the "viewer" component. The HTML content loaded looks like an "university report" (it's just a formatted text, only <span> and <p> with class="..." attributes, nothing more).
Ex : <p>Lorem ispum <span>some text</span> loreb bis <span>ipsum</span></p> ...
I load the content, and inject it this way in the render() of my component <Viewer> :
<div dangerouslySetInnerHTML={ getFreshlyLoadedHTML() } />
Easy, it works just fine !
But... Now, I want to inject some "interactive" components in the loaded HTML. For example, some button to give a feedback etc. The API must decide where to place the component between the words/nodes of the formatted text (HTML).
Ex :
<p> Lorem ispum <span>some text</span>
loreb bis <span>ipsum</span>
<MyFeedbackButton paragraph="1.3"/>
</p><p>Other Lorem Ipsum<p><span>...</span>
There, I'm stucked because I cannot use dangerouslySetInnerHTML if there are components inside the loaded HTML...
First attempt : I've tried modifying the API, and instead of sending the HTML in a string to the app, I send a custom JSON structure that represents almost the final JSX structure that I want. Then, in my react page, the render function only have to parse the JSON and build the JSX (here, a JsFiddle example if it's not clear : https://jsfiddle.net/damienfa/69z2wepo/34536/ )
It works, but I can't believe it's the good way...
I see a major problem : all the HTML node (span, p...) that I build from the render function are referenced by reactJs, is it really necessary ? Mostly, there are "dead" nodes (I mean, dom node that won't never changed, this is static formatted text).
Just take a look a all those "data-reactid" on nodes that never will be interactive...
What would be your advice on that case ?
What about my attempt with a JSON-structure sent by the API ?
Is there a way to say to react "do not reference that element" ?
Do you clearly see a better solution to my problem ?
Your current workflow is not very secure and subject to many potential errors and open doors, especially concerning code injection ...
The overload due to react tracking the nodes is not an issue, React could track 10 000 nodes and not have a problem (well actually on many of my apps React has more than 100 000 nodes to care about and it still rurns perfectly).
I see different solutions here:
If there are only 3 or 4 possibilities of dynamic components and order, you might have components like "templates" to which you would simple send text arguments. This is the safest and easiest option.
If it doesn't suit your use-case but the JSON file can contain only a limited set of components, the components should be located in your main app, and then rendered with custom props from the JSON. Actually given the structure of data you could consider using xml instead of json and build a xml tree that you would parse and render. Only components from your white list would be rendered and it would limit drastically the potentials security issues. If needs quite some work on the XML parser though.
If the JSON file can contain many many different and unpredictable components or if the behaviour of those components is largely dynamic and independant of your app, you might as well consider using an iframe, with its own JS and HTML, so that this part of the code is isolated from the rest.
Try using an inline anonymous function within the inner content from within React using JSX. It works! Just be careful about how you wire up the data so there isn't a route where a user can inject HTML from an input or text field.
<div className="html-navigation-button">{(() =>
{
const CreateMarkup = ( sNavItemName :string ) => {
return {__html: sNavItemName };
}
var sTextToAddHtmlTo = props.nextNavItem.name.toString();
sTextToAddHtmlTo = sTextToAddHtmlTo.replace( "/", "/<wbr>" );
return (
<div dangerouslySetInnerHTML={CreateMarkup( sTextToAddHtmlTo )} >
</div>
);
})()}
</div>
I didn't override the React internals of 'render()', but only used a React Component with props wiring to pass down data to it for rendering.
I added the hook for 'dangerouslySetInnerHTML' deep within the return content of the React Component so there would be no easy way to intercept and manipulate it.
As such, there is no 100% guarantee on safety, but that's where adding good security to web services, databases, and use of CORS and CORB would be helpful to lock down security risks.

AngularJS custom ng-repeat with recursion not working

The issue is best illustrated in the plunker - http://plnkr.co/edit/9DYQ3rlmiMK9bdtjyYOA.
Basically, I am trying to create a meta form rendering engine using angular with the help of directives that handle interpretation of data runtime and render the fields accordingly.
Please let me know if you have any ideas why the dyn-ng-repeat directive is not rendering the three URL fields under the user object as expected in the code below -
<div dyn-ng-repeat="item in {{field.model}}">
<div ng-repeat="field in field.children" ng-include src="'field.html'">/div>
</div>
Thanks.
EDIT:
Hi guys, I have created a full Plunker here - http://plnkr.co/edit/cFreJZbluy3w4R9PZUCD?p=preview that should have all the code necessary but not working.
Basically, there is a hierarchy of objects. Social Networks have URLS and a list of Friends. The code is supposed to display three social networks and each should have two friends listed under them. The button 'Add Network' should add another social network to the list and the button 'Remove Network' should remove the respective network associated with it along with all its children. Similarly, 'Add Friend' should add a new friend object under that Social Network and 'Remove Friend' should remove the respective friend from under that network.
It's a bit complex, but if you look at it for a couple of minutes, you'll get the idea of what I'm trying to do here. It's dynamic DOM based on the data elements that are bound two way.
Thanks.

Meteor - how to link html element to database entry on click event?

I'm trying to figure out how to link an html picture element back to the database entry that was originally used to generate the picture link.
I am using Meteor:
- I have a database that contains photosets data from Flickr API
- In the HTML, I have a handlebar "each" script that iterates through each photoset in the database and then uses this info to generate the html for the photoset cover picture links.
- When the html renders, the photoset cover pictures are downloaded from Flickr and displayed to the screen.
I would like to be able to click on the photoset cover picture and then automatically generate the links to the pictures in the photoset. But I don't understand how to dynamically link the html picture elements back to their respective database entries that were originally used for generating the picture links. I need to be able to find the original database entries so that I can load the info needed for generation of subsequent links.
As a newb to all of this I'm not really sure where to start looking or what to try. I've wondered about creating an object with custom key pairs to 'memorise' the identity of each photoset picture. Is this the way to go, or is there an easier way that I am overlooking?
Thanks.
Say you have your pictures being put out this way:
Template.mytemplate.helpers({
picture:function() {
return pictures.find()
}
});
You can also do this instead, which is pretty much the same thing:
Template.mytemplate.picture = function() {
return pictures.find();
}
With the html
<template name="pictures">
{{#each picture}}
<img src="{{src}}" class="pictureselector"/>
{{/each}}
</template>
You can use events which can get data from that particular picture document/record
Template.mytemplate.events({
'click .pictureselector':function(event,template) {
console.log(this._id); //Should give you the `_id` of the picture that was clicked
}
});
this is the data context of the element that was clicked & generate the link you want using the data inside this.
Be careful if you use something with a callback inside the click like Meteor.call, you will have to relay the message down via var self = this otherwise the context of this would become the one of Meteor.call

Resources