Create Route to Simple Page Reaction Commerce - meteor

I am trying to setup a simple static page for about us, based on this tutorial (https://docs.reactioncommerce.com/reaction-docs/master/plugin-routes-6). The problem is that there is no real explanation on what I need to do outside adding an entry to the registry.js file. While they do have the plugin example that I could copy, I would like to know what I need to just add a simple static page to Reaction Commerce. Thanks.
Wade

To create the simple route for the page, given tutorial is what we all got.
To Create route for a page:
I will break it down for you in following steps:
I will assume that you know we have to add our code in the /imports/plugin/custom directory only. You can override all the core functionality from here.
Let's get started:
You need to add route details in the registry under register.js file.
registry:[
{
route:"/about",
name:"about",
template:"aboutUs",
workflow:"coreWorkflow"
}
],
Create the component for a new page as
/imports/plugin/custom/YOUR_PLUGIN/client/components/about.js in your plugin.
import React, { Component } from "react";
import { registerComponent } from "/imports/plugins/core/components/lib";
import { Meteor } from "meteor/meteor";
import { Col } from 'reactstrap';
class About extends Component {
render() {
return (
<div className="container-main">
About Us Page
</div>
);
}
}
registerComponent("about", About);
Add the button to route to the new page, in any component, from where you can give link to About page.
<Components.Button
label="About"
onClick={handleClick}
/>
Add function to handle the click.
handleClick() {
return Reaction.Router.go("/about");
}
Hope this solves your query!
PS: I know this code can be shortened, I have written it in this way so that beginners can understand it faster. Please don't hesitate to correct the answer if I am wrong. :)

Related

nextjs links without strings

Im new to nextjs, and Im checking if it will be good for the app that will have pretty complex and messy internal navigation. Just checked their documentation and I see that they recommend usage
of Link component like this <Link href="/your_path">Path</Link>. A bit scary is that I have to provide 'your_path' as a string so every time i change page file name I have to manually update code that redirects to this page. Is there any solution that allows me to define routing on my own so I can write something like (pseudocode)
routes = [
...
{
page : 'page_name',
path : 'path_to_page'
}
...
]
So instead of using string I can do <Link href="{route.path}">Path</Link> or Im condemned to use this file-system based router with all consequences?
The simple answer is yes!
When you want to change a user route in NextJs you have 2 options,
The first is with the <Link> Element that you can specify a href to where it directs.
And you also have a useRouter hook for more complex routing for example if the user does an action that requires moving him into a different route you can do it internally in your handlers.
For more information about useRouter hook.
What I usually do is storing my routes in an object
const ROUTES = {
HOME: "/",
ABOUT: "/about"
}
and wherever you call routes you just use the object so F.E
With Link tag
<Link href={ROUTES.ABOUT}>ABOUT PAGE</Link>`
with useRouter hook
// Inside a React Component
const router = useRouter();
const handleNavigateToAbout = () => {
router.push(ROUTES.ABOUT);
}
return (
// SOME JSX
<button onClick={handleNavigateToAbout}> Go to about page! </button>
)

Next.js _app and _document use?

I'm totally new with next.js and I need your help for something I guess really basic but I cannot find my mistake or an explanation, I found nothing on the internet about it, so here I am :
Everything works when I create a file in the pages folder(I mean every file in pages folder is ok except _app.js or _document.js), I can reach the URL, but I would like to use context, layout or authentification in the future and I need to use the _app and _document override cool things but I can write anything I want in it, it seems my _app.js or _document.js are just useless, never called or I don't know but they just never work.
I tried on 2 projects, here is what I do according to the next documentation :
first, npx create-next-app to create the project, and then add an _app.js for example in pages folder and add :
import React from 'react'
import App from 'next/app'
import Nav from '../components/nav'
class MyApp extends App {
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// static async getInitialProps(appContext) {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
render() {
const { Component, pageProps } = this.props
return (
<>
<Nav />
<Component {...pageProps} />
</>
);
}
}
export default MyApp
Anybody could tell me what I am doing wrong?
Well, if anybody is going through the same issue, I found what was going on, in fact, after creating for the first time _app.js, I have to restart my docker container, or restart my app with yarn next dev if I want to see the changes or they never appear. I am going to look for more explanations on how SSR and next.js more globaly exactly work to understand their behaviour on this point. Good luck all !

METEOR: how to redirect after logout

I am quite new to Meteor & React. Here I would like to redirect my currect user to home page whenever the logout button is pressed. Attached you can see the protected page template with the logout button.
Please note that I am working with the latest versions (Meteor 1.6.1 and React V4).
import React from 'react';
import { Accounts } from 'meteor/accounts-base';
export default class Link extends React.Component{
onLogout(){
Accounts.logout()
};
render(){
return(
<div>
<p>Private Content goes here</p>
<button onClick={this.onLogout.bind(this)}>Logout</button>
</div>
);
}
};
any kind of support will be appreciated.
There are two main options to use here:
1. Pass a callback to Accounts.logout(func)
This is the simplest but mixes the return behavior into your component, which is not ideal.
2. Use Accounts.onLogout(func)
You could put this with your accounts initialization or with your router code, whichever keeps the logic grouped together best for your app.
In that callback, you'll want to use your router to redirect. The exact syntax will depend on your router, but will generally look like:
Router.go('/')
Another way, if you are setting things via meteor-useraccounts way...
const myLogoutFunc = function() {
FlowRouter.go('/login');
}
AccountsTemplates.configure({
// Hooks
onLogoutHook: myLogoutFunc,
onSubmitHook: mySubmitFunc,
preSignUpHook: myPreSubmitFunc,
postSignUpHook: myPostSubmitFunc,
});
Template event code is something like this..
'click .logout': () => {
AccountsTemplates.logout();
}
Read in detail here https://github.com/meteor-useraccounts/core/blob/master/Guide.md

How can I change the subscriptions query parameters in react-komposer (meteor) from a child component?

I'm building an app with Meteor using the react-komposer package. It is very simple: There's a top-level component (App) containing a search form and a list of results. The list gets its entries through the props, provided by the komposer container (AppContainer). It works perfectly well, until I try to implement the search, to narrow down the results displayed in the list.
This is the code I've started with (AppContainer.jsx):
import { Meteor } from 'meteor/meteor';
import { composeWithTracker } from 'react-komposer';
import React, { Component } from 'react';
import Entries from '../api/entries.js';
import App from '../ui/App.jsx';
function composer(props, onData) {
if (Meteor.subscribe('entries').ready()) {
const entries = Entries.find({}).fetch();
onData(null, {entries});
};
};
export default composeWithTracker(composer)(App);
App simply renders out the whole list of entries.
What I'd like to achieve, is to pass query parameters to Entries.find({}).fetch(); with data coming from the App component (captured via a text input e.g.).
In other words: How can I feed a parameter into the AppContainer from the App (child) component, in order to search for specific entries and ultimately re-render the corresponding results?
To further clarify, here is the code for App.jsx:
import React, { Component } from 'react';
export default class App extends Component {
render() {
return (
<div>
<form>
<input type="text" placeholder="Search" />
</form>
<ul>
{this.props.entries.map((entry) => (
<li key={entry._id}>{entry.name}</li>
))}
</ul>
</div>
);
}
}
Thanks in advance!
I was going to write a comment for this to clarify on nupac's answer, but the amount of characters was too restrictive.
The sample code you're looking for is in the search tutorial link provided by nupac. Here is the composer function with the corresponding changes:
function composer(props, onData) {
if (Meteor.subscribe('entries', Session.get("searchValues")).ready()) {
const entries = Entries.find({}).fetch();
onData(null, {entries});
};
};
The solution is the session package. You may need to add it to your packages file and it should be available without having to import it. Otherwise try with import { Session } from 'meteor/session';
You just need to set the session when submitting the search form. Like this for instance:
Session.set("searchValues", {
key: value
});
The subscription will fetch the data automatically every time the specific session value changes.
Finally, you'll be able to access the values in the publish method on the server side:
Meteor.publish('entries', (query) => {
if (query) {
return Entries.find(query);
} else {
return Entries.find();
}
});
Hope this helps. If that's not the case, just let me know.
There are 2 approaches that you can take.
The Subscription way,
The Meteor.call way,
The Subscription way
It involves you setting a property that you fetch from the url. So you setup your routes to send a query property to you Component.Your component uses that property as a param to send to your publication and only subscribe to stuff that fits the search criteria. Then you put your query in your fetch statement and render the result.
The Meteor.call way
Forget subscription and do it the old way. Send your query to an endpoint, in this case a Meteor method, and render the results. I prefer this method for one reason, $text. Minimongo does not support $text so you cannot use $text to search for stuff on the client. Instead you can set up your server's mongo with text indexes and meteor method to handle the search and render the results.
See what suits your priorities. The meteor.call way requires you to do a bit more work to make a "Search result" shareable through url but you get richer search results. The subscription way is easier to implement.
Here is a link to a search tutorial for meteor and read about $text if you are interested

How can I use Angular 2 in a .NET 4 Web Forms project?

I have a ASP.NET 4 Web Forms project written in C#. I would like to add Angular 2. I've seen a lot of examples on the web using ASP.NET 5 but I can't figure out how to do it in my project.
Have faced similar requirement and did some POC on this and definitely moving forward with it . I worked on with each .aspx page as stand alone angular 2 SPA app. This means each aspx page will have its own App.Component.ts and main.ts file(file name based on Angular 2 documentation). main.ts file contains the code to bootstrap the application (sample code below) so there will be a main.ts file for each .aspx page.
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_BINDINGS} from 'angular2/http';
import {HomeComponent} from './home.component';
bootstrap(HomeComponent, [HTTP_BINDINGS])
.catch(err => console.error(err));
There will be one app.component.ts(named it home.component.ts for my home.aspx) file for each aspx page.
Now in the config file which contains Sytem.config details i defined new map and package entry for my home.aspx as shown below:
System.config({
transpiler: 'typescript',
typescriptOptions: {
emitDecoratorMetadata: true,
experimentalDecorators: true
},
map: {
app: '../../Javascript/angular/app',
home: '../../Javascript/angular/home'
},
packages: {
app: { main: './main.ts', defaultExtension: 'ts'},
home: { defaultExtension: 'ts' }
}
});
And finally I moved the System.import code part to .aspx page(code below). Each page will import its own package defined in sytem.config.
<script>
System
.import('home/main-home')
.catch(console.error.bind(console));
</script>
here i have named my main.ts as main-home.ts.
Hopefully this helps you and others. Also i am open for suggestion and review/alternate solution of this approach.
For reference please see: bootstrapping-multiple-angular-2-applications-on-the-same-page
I totally agree with #pawan's answer but yes #pawan i found a nice solution of this. This solution definitely helped me and hope it will help all of you too.
We don't need to create main.ts and AppComponent.ts for each and every page.
We need to make our main component which we are bootstrapping dynamic. In our case, in app.component.ts, i am bootstrapping our component dynamically based on url of current page.
Let's say if your page is home.aspx then boostrap HomeComponent or about.aspx then boostrap AboutComponent
I am doing it by implementing ngDoBootstrap method as following.
export class AppModule {
url : string;
constructor(#Inject(DOCUMENT) private document: any){
this.url = this.document.location.href.toLowerCase();
}
ngDoBootstrap(app:ApplicationRef){
if(this.url.indexOf("home.aspx") > 0){
app.bootstrap(HomeComponent);
}
else if(this.url.indexOf("about.aspx") > 0){
app.bootstrap(AboutComponent);
}
}
}
This is how based on page url, we can dynamically bootstrap our Component and save a lot files of main.ts and app.component.ts for each page.
For this, you need to add entry for each component into entryComponents array of NgModule as below:
#NgModule({
entryComponents : [
HomeComponent,
AboutComponent,
]
})
Hope this helps.
change your index.html base route to your webpage
<base href="/YourWebPageRoute">
include the page inside the webform
<% Response.WriteFile("index.html"); %>

Resources