How to add data to SharePoint list with SPFx using React Functional component? - sharepoint-online

I have created an SPFx React solution with the Class components and performed CRUD operations with the SharePoint list.
I have used #pnp/sp for SharePoint API calls.
Now, I need to perform CRUD operations in the SPFx React solution with the Functional components.
Can anyone suggest useful links for the same?
Thanks

Its the same in Functional components.
import * as React from 'react';
import "#pnp/sp/webs";
import "#pnp/sp/lists";
import "#pnp/sp/items";
import { SPFI } from '#pnp/sp';
const SimpleFunctionComponent:React.FunctionComponent<{sp: SPFI}> = ({sp}) => {
const [ items, setItems ] = React.useState<string[]>([]);
React.useEffect(() => {
const init = async () => {
const items: any[] = await sp.web.lists.getByTitle("Test").items();
setItems(items.map(i => i["Title"]));
};
if(sp) {
init();
}
}, [sp]);
return <div>
{
items.map(i => <div>{i}</div>)
}
</div>
}
export { SimpleFunctionComponent }
You have the SPFI property (you can define and init it in the webpart.ts file). Then in the component itself you can have an useEffect hook to load items for example. The hook I use in the example will load everytime the "sp" property is changing. The result will look like this:

Related

How to get method and its metadata from NestJS provider?

I'm making a NestJS wrapper for Typegoose because the existing one is complete deprecated and has one critical drawback that I want to fix in my implementation.
Problem: there is #EventTrackerFor(schema: AnyClass) that takes Typegoose class. It's implemented like this:
export const EventTrackerFor = (schema: AnyClass) =>
applyDecorators(Injectable, SetMetadata('tracker-for', schema.name));
Also, there are #Pre(eventName: PreEvents) and Post(eventName: PostEvents) decorators:
export const Post = (eventName: PreEvents) => SetMetadata('post', eventName);
export const Pre = (eventName: PostEvents) => SetMetadata('pre', eventName);
And as a result, library user will do it like that:
#EventTrackerFor(User)
class UserEventTracker {
constructor(private readonly anyService: AnyService) {}
#Pre(PreEvents.SAVE)
#Post(PostEvents.SAVE)
logOnAndAfterCreate() {
console.log('user created')
}
}
// ------------------------ Any module
#Module({
imports: [MyModule.forFeature([ {schema: User} ])],
providers: [UserEventTracker]
})
class AnyModule {}
I need to get value from #EventTrackerFor somehow and methods of the provider, which are decorated with #Pre() and #Post decorators, including values that passed inside them.
I was looking for a clue in different packages like #nestjs/bull, which has similar logics inside, but they have so much code, so I could not understand how do they do it.
Project repository: https://github.com/GrapeoffJS/kindagoose

A clean way to check for query parameter in NestJS

I have a nestjs project that is mostly in RESTful structure. Everything works fine, but my concern is that some of the routes check for the presence of some query parameters to fetch data.
for instance
#Get('/some-resources')
async getSomeResource(
#Query() query: any
): Promise<HTTPResponseDTO>{
const startDate = query.startDate ? DateTime.fromISO(query.startDate).startOf('day').toISO(): null;
const endDate = query.endDate ? DateTime.fromISO(query.endDate).endOf('day').toISO() : null;
.
.
.
const result = await this.someResourceService.findAll(startDate, endDate,...)
}
Now my question is, is there a cleaner approach to this? Because this can get become a pain to maintain when we have many resources.
As mentioned by Micael Levi, you should be able to do this by creating your own custom pipe. Assuming that what you posted works, you should be able to do something along the lines of:
#Get('/some-resources')
async getSomeResource(
#Query('startDate', ParseDateIsoPipe) startDate?: string,
#Query('endDate', ParseDateIsoPipe) endDate?: string
): Promise<HTTPResponseDTO>{
<code>
}
With your ParseDateIsoPipe as follows (Note that you will still need to import DateTime from the package you are using):
import { PipeTransform, Injectable, ArgumentMetadata } from '#nestjs/common';
#Injectable()
export class ParseDateIsoPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
return value ? DateTime.fromISO(value).startOf('day').toISO(): null;
}
}
You can use the built-in validation pipe: https://docs.nestjs.com/techniques/validation with the auto validation feature.

How to use any of i18n packages in nestjs mvc?

I found this package nest-18n but that dudes thinks that nestjs is only used for api and not mvc.
So sure ?lang=en or ?lang=de works and it changes language but question is how to use that on view?
My first thought was that this is working out of the box with __("Something to translate"). But that will not work (__ is undefined).
Since i18Service.translate method is async you can not add it to view (there is pug then but that is horrible idea). Idea of adding anything on the the view that is async does not make sense at all. So in principle they made package that can not be used outside of api's.
Other thing that i can do is to have something like
class AppController extends BaseController() {
#Get("/")
index() {
return {
someTranslation: await this.getTranslation("give me something to translate"),
// IMAGINE NOW Having 1000 OF TRANSLATION ON INDEX PAGE
}
}
}
where BaseController is:
class BaseController() {
constructor(private readonly i18n: I18nService, lang: string) {
}
async protected getTranslation(stringToTranslate: string) {
return await this.i18n(stringToTranslate, {lang});
}
}
Does anyone have idea how to use any of i18n in nestjs mvc?

Git message type on library update

I make my own react boilerplate and come until updating packages. So I've update react across major version (v15x to v16x), and change my code on a module file called injectReducer. So what i've changed in injectReducer is from this:
static contextTypes = {
store: PropTypes.object.isRequired,
};
to this:
static contextType = ReactReduxContext;
Now I think this doesn't do any breaking changes on my boilerplate, because the use of the module still the same (backward compatible). But what about the package I've updated? Should any library updated across major is considered breaking changes? What about minor updates?
Here is my full code of injectReducer:
import React from 'react';
import { ReactReduxContext } from 'react-redux';
import hoistNonReactStatics from 'hoist-non-react-statics';
import getInjectors from './reducerInjectors';
export default ({ key, reducer }) => (WrappedComponent) => {
class ReducerInjector extends React.Component {
static WrappedComponent = WrappedComponent;
static displayName = `withReducer(${(WrappedComponent.displayName || WrappedComponent.name || 'Component')})`;
static contextType = ReactReduxContext;
injectors = getInjectors(this.context.store);
componentWillMount() {
const { injectReducer } = this.injectors;
injectReducer(key, reducer);
}
render() {
return <WrappedComponent {...this.props} />;
}
}
return hoistNonReactStatics(ReducerInjector, WrappedComponent);
};
But what about the package I've updated? Should any library updated across major is considered breaking changes?
That is the idea behing the major version in semver
when you make incompatible API changes
Except I would consider it does not involve just the API.
See as an example "Semantic Versioning, Go Modules, and Databases" (just to illustrate the kind of non-API change which would still warrant a major version bump)
Basically, if any client of your library has work to do in order to adapt to the new version... your change should be considered major.
If not: minor.

Get translation text without using FormattedMessage and React ContextTypes

I'm looking for a way to get translation text without using FormattedMessage. Until now, I've found only this solution that provides to use ContextTypes an React's EXPERIMENTAL feature. Are there others ways to accomplish this (or other library/npm module)?
I prefer using context, but react-intl does also provide a higher order component injectIntl you can use instead. This will pass a prop intl that has all the imperative formatting functions.
import React from "react";
import {injectIntl, intlShape} from "react-intl";
class MyComponent extends React.Component {
static propTypes = {
intl: intlShape.isRequired
}
render() {
return <p>{this.props.intl.formatDate(new Date())}</p>;
}
}
export default injectIntl(Component);

Resources