I have a collection named LibraryItems which is available on both client and server side.
api/libraryitems/libraryitems.js
import { Mongo } from 'meteor/mongo';
const LibraryItems = new Mongo.Collection('libraryitems');
export default LibraryItems;
Instead of an if (Meteor.isServer) {..} publication in this same file, I would like to have a server folder with the specific publications:
api/libraryitems/server/publications.js
import LibraryItems from '../libraryitems';
import { Meteor } from 'meteor/meteor';
Meteor.publish('LibraryItems.pub.all', function () {
return LibraryItems.find({});
});
But somehow, against my expectations, this publication is not available...
update
This is my subscription code (meteor+reactjs):
./imports/ui/Library.js
import LibraryItems from '../api/libraryitems/libraryitems';
import { createContainer } from 'meteor/react-meteor-data';
...
export default createContainer(() => {
Meteor.subscribe('LibraryItems.pub.all');
var libraryitems = LibraryItems.find().fetch();
return {
libraryitems: libraryitems
}
}, Library);
You are exporting LibraryItems as a default export, that means when you import it you don't need curly brackets around it.
Change your import to:
import LibraryItems from '../libraryitems';
Also, clean up the publication code slightly:
return LibraryItems.find({});
EDIT
Now that you have posted your subscription code as requested, I see that you are subscribing to the publication with a different name.
Change to:
Meteor.subscribe('LibraryItems.all');
Hope that helps
I forgot to register the publications in mains.js:
import '../imports/api/libraryitems/server/publications';
Related
How to use Redux inside NEXTJS middleware?
Any suggestion to achieve this problem, I try my useSelector in my index it's works fine but in middleware I don't know how to use it I'm newbie in nextjs.
//middleware.js
import { NextResponse } from 'next/server';
import { useSelector } from "react-redux";
import { store} from './store/store';
export function middleware(request) {
const auth = store.getState().user;
if (request.nextUrl.pathname.startsWith('/login')) {
if(auth ){
return NextResponse.rewrite(new URL('/' , request.url))
}
}
if (request.nextUrl.pathname.startsWith('/dashboard')) {
// This logic is only applied to /dashboard
}
}
It seems like reducers are not meant to be changed server side. I read a very similar issue here https://github.com/reduxjs/redux/issues/1745 Give it a try. Hope its helpful.
In Deno it is possible to version the dependencies in the import statement, and there's no package.json like with npm.
But how to managed it's URLs and versions in a single place?
I will have multiple files and dependencies that will be declared all over my system.
For example:
dateUtils.ts
import { parseDate } from 'https://deno.land/std#0.50.0/datetime/mod.ts';
const DEFAULT_MASK = "dd-mm-yyyy";
export function parse(date: string): Date {
return parseDate(date, DEFAULT_MASK);
};
service.ts
import { v4 } from "https://deno.land/std/uuid/mod.ts";
export function process(request: any) {
const { token } = request;
const isValid = v4.validate(token);
console.log(`Token validity: ${isValid}`)
};
app.ts
import { parse } from "./dateUtil.ts";
import * as service from "./service.ts";
const date = parse("20-05-2020");
console.log(date);
const request = {
token: "408d30e5-1e90-45e3-b299-6520feee6d76"
}
service.process(request)
To avoid typing https://deno.land/std/uuid/mod.ts everywhere you can use import maps
// import_map.json
{
"imports": {
"http/": "https://deno.land/std/http/"
}
}
// server.ts
import { serve } from "http/server.ts";
const body = new TextEncoder().encode("Hello World\n");
for await (const req of serve(":8000")) {
req.respond({ body });
}
deno run --importmap=import_map.json --allow-net server.ts
import maps are currently unstable, but you can use them behind --unstable flag.
Aside from that it's common to have a deps.ts file where you'll re-export all your dependencies.
// deps.ts
export * as path from "https://deno.land/std#0.51.0/path/mod.ts";
// other exports .. from
// some other file
import { path } from './deps.ts' // instead of "https://deno.land/std#0.51.0/path/mod.ts"
path.basename('/bar/test.txt');
In deno there is a convention for consolidating imports into deps.ts.
export { parseDate } from 'https://deno.land/std#0.50.0/datetime/mod.ts';
export { v4 } from "https://deno.land/std/uuid/mod.ts";
Exports can then be imported in other modules/scripts on your application:
import { v4 } from "./deps.ts";
import { parseDate } from './deps.ts';
const myUUID = v4.generate();
parseDate("20-05-2020", "dd-mm-yyyy")
When using this approach one should consider integrity checking & lock files:
// Add a new dependency to "src/deps.ts", used somewhere else.
export { xyz } from "https://unpkg.com/xyz-lib#v0.9.0/lib.ts";
# Create/update the lock file "lock.json".
deno cache --lock=lock.json --lock-write src/deps.ts
# Include it when committing to source control.
git add -u lock.json
git commit -m "feat: Add support for xyz using xyz-lib"
git push
In meteor project, do I need to import {Meteor},{Mongo}, and{check} in this example? Why?
collections.js
// import {Mongo} from 'meteor/mongo' // ---- i have to import this?
Bookmarks = new Mongo.Collection('bookmarks')
methods.js
// import {check} from 'meteor/check' // ---- i have to import this?
import {Bookmarks} from "/imports/schema/bookmarks/index"
Meteor.methods({
'bookmark.add'({name, url}){
check(name,String) // ---------------
check(url,String)
const bookmarkId = Bookmarks.insert({name,url})
Meteor.isServer && console.log(`Id ${bookmarkId} inserted`)
},
'bookmark.remove'(_id){
check(_id,String)
const bookmark = Bookmarks.findOne({_id})
if (!bookmark){
Meteor.isServer && console.log('no such a bookmark!')
} else {
const removeBookmarkId = Bookmarks.remove({_id})
Meteor.isServer && console.log(`remove result ${removeBookmarkId?'success':'error'}`)
}
}
})
The short answer is yes. Meteor makes heavy use of the module system for imports and exports. You can read more about how Meteor modules works, and the reasons motivating the move to Meteor modules here.
Is it ok to have a reducer calling sub-reducers in its default block?
function aReducer(state = {}, action) {
switch(action.type) {
case XYZ:
... // know what to do
default:
// don't know this action, let's delegate to the children
return {
sub1: subReducer1(state.sub1, action),
sub2: subReducer2(state.sub2, action)
}
}
}
Yes, that's absolutely legal and reasonable to do.
You might want to read through the Redux docs section on "Structuring Reducers" for further ideas on how you can organize reducer logic as well.
You can put all the reducers in a common folder and inside that, you can combine the separate reducers into a single one like the following code.
import { combineReducers } from 'redux'
import Reducer1 from './Reducer1.js'
import Reducer2 from './Reducer2.js'
export default combineReducers( { Reducer1, Reducer2,... } )
and use the following code to use that as a single reducer.
import reducers from '../../reducers'(reducer's root folder name/path)
let store = createStore( reducers );
I am trying to implement alanning Meteor-roles with react-router in my Meteor application. Everything is working fine except the fact I can't manage properly to restrict a route using alanning roles or Meteor.user()
I tried with meteor-roles:
I am trying to use the onEnter={requireVerified} on my route. This is the code:
const requireVerified = (nextState, replace) => {
if (!Roles.userIsInRole(Meteor.userId(), ['verified'],'user_default')) {
replace({
pathname: '/account/verify',
state: { nextPathname: nextState.location.pathname },
});
}
};
I tried with Meteor.user():
const requireVerified = (nextState, replace) => {
if (!Meteor.user().isverified == true) {
replace({
pathname: '/account/verify',
state: { nextPathname: nextState.location.pathname },
});
}
};
So this is working when I am clicking on a route link, but when i manually refresh (F5), it does not work. After digging into it, i have found that Meteor.user() is not ready when i manually refresh the page.
I know Meteor.userid() or Meteor.logginIn() are working, but i wanted
to verify not just that they are logged but if they are "verified" or
have a role.
I also tried to check inside the component with react, with componentDidMount() or componentWillMount(), in both cases it's the same, the manual fresh does not load Meteor.user() before the compenent is mounted.
So what is the best way to restrict components/routes with meteor/alaning roles + react router ? (I am using react-komposer inside TheMeteorChef's base)
Thank you.
Note I have not tried it yet, it's only a suggestion
One thing you could try is to use componentWillReceiveProps alongside createContainer from 'react-meteor-data' like that:
import React, { Component, PropTypes } from 'react';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { Roles } from 'meteor/alanning:roles';
class MyComponent extends Component {
componentWillReceiveProps(nextProps) {
const { user } = nextProps;
if (user && !Roles.userIsInRole(user._id, ['verified'], 'user_default')) {
browserHistory.push('/account/verify');
}
// If Meteor.user() is not ready, this will be skipped.
}
}
MyComponent.propTypes = {
user: PropTypes.object,
};
export default createContainer(() => {
const user = Meteor.user() || null;
return { user };
}, MyComponent);
To explain the flow, when the page is loaded, as you said Meteor.user() is not defined so you can't check the permissions. However, when Meteor.user() gets defined, this will trigger a refresh of the template, and the new props will be passed to componentWillReceiveProps. At this moment you can check if user has been defined and redirect if needed.
To be really sure not to miss anything, I would actually put the verification in the constructor() as well (defining a function that takes the props as arguments and calling it in both constructor() and componentWillReceiveProps()).