I am using this code in my webpart to insert into the sharepoint list with list name, but moving this code into production environment is creating an issue since its forming the wrong url for inserting into the list, The url in production is
https://abcportal.sharepoint.com/sites/SolutionBook/SitePages/_api/web/lists/getByTitle('Smart%20City%20IAQ%20Demo%20Requests')?$select=ListItemEntityTypeFullName
But in local environment is working fine it forms this url
https://abcportal.sharepoint.com/sites/solutionbooktest/_api/web/lists/getByTitle('Smart City IAQ Demo Requests')/items
In the production environment URL SitePages is coming automatically, how to remove it?
-------Code---------
public insertEmailToList() {
pnp.sp.web.lists.getByTitle("Smart City IAQ Demo Requests").items.add({
Title: this.state.Email
}).then(r => {
this.setState({ ButtonActive: false });
});
}
or Is there any way to insert into sharepoint list using URL of the list?
You need to establish the SPFx context for PnPJs. This can be done in the onInit() method of your web part through the setup() method imported from #pnp/core or #pnp/sp.
Using #pnp/core setup
import { setup as pnpSetup } from "#pnp/core";
// ...
protected onInit(): Promise<void> {
return super.onInit().then(_ => {
// other init code may be present
pnpSetup({
spfxContext: this.context
});
});
}
// ...
Using #pnp/sp setup
import { sp } from "#pnp/sp/presets/all";
// ...
protected onInit(): Promise<void> {
return super.onInit().then(_ => {
// other init code may be present
sp.setup({
spfxContext: this.context
});
});
}
// ...
Refer to this link for more details.
Related
I want to modify create-react-app service worker file and implement popup message which will ask user to update app if newer service worker is ready to be activated. I'm almost done with the solution but have one pitfall. I want to reload the app when user confirms service worker update popup, so I've added some coded to the end of register function, see below:
export default function register(config) {
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return
}
window.addEventListener("load", () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config)
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
"This web app is being served cache-first by a service " +
"worker."
)
})
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl, config)
}
let preventDevToolsReloadLoop
navigator.serviceWorker.addEventListener("controllerchange", function() {
// ensure refresh is called only once
if (preventDevToolsReloadLoop) {
return
}
preventDevToolsReloadLoop = true
console.log("reload")
window.location.reload(true)
})
})
}
}
But the problem is that it reloads the app also on first visit, when there doesn't exist any service worker yet. How can I solve it?
Update to react-scripts ^3.2.0. Verify that you have the new version of serviceWorker.ts or .js. The old one was called registerServiceWorker.ts and the register function did not accept a configuration object. Note that this solution only works well if you are Not lazy-loading.
then in index.tsx:
serviceWorker.register({
onUpdate: registration => {
alert('New version available! Ready to update?');
if (registration && registration.waiting) {
registration.waiting.postMessage({ type: 'SKIP_WAITING' });
}
window.location.reload();
}
});
The latest version of the ServiceWorker.ts register()function accepts a config object with a callback function where we can handle upgrading. If we post a message SKIP_WAITING this tells the service worker to stop waiting and to go ahead and load the new content after the next refresh. In this example I am using a javascript alert to inform the user. Please replace this with a custom toast.
The reason this postMessage function works is because under the hood CRA is using workbox-webpack-plugin which includes a SKIP_WAITING listener.
More About Service Workers
good guide: https://redfin.engineering/how-to-fix-the-refresh-button-when-using-service-workers-a8e27af6df68
CRA issue discussing service worker cache: https://github.com/facebook/create-react-app/issues/5316
If you are not using CRA, you can use workbox directly: https://developers.google.com/web/tools/workbox
Completing #jfbloom22's answer:
As you probably want to ask the user after an update has been detected with something more complex than a plain alert, you need to ensure the registration object is available from inside the React's components tree and save it to use after the user accepts to update (for example, by clicking a button).
As an option, in a component you can create a custom event listener on a global object like document and fire this event when the onUpdate callback passed to serviceWorker.register(), passing to it the resgistration object as extra data.
This is exactly what my recently published Service Worker Updater does (some self-promotion). To use it you just need to:
Add it to the dependencies:
yarn add #3m1/service-worker-updater
Use it in your index.js:
import { onServiceWorkerUpdate } from '#3m1/service-worker-updater';
// ...
// There are some naming changes in newer Create React App versions
serviceWorkerRegistration.register({
onUpdate: onServiceWorkerUpdate
});
Use it in some of your React components:
import React from 'react';
import { withServiceWorkerUpdater } from '#3m1/service-worker-updater';
const Updater = (props) => {
const {newServiceWorkerDetected, onLoadNewServiceWorkerAccept} = props;
return newServiceWorkerDetected ? (
<>
New version detected.
<button onClick={ onLoadNewServiceWorkerAccept }>Update!</button>
</>
) : null; // If no update is available, render nothing
}
export default withServiceWorkerUpdater(Updater);
Try to add reload funtion in installingWorker.state === 'installed'
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// do something ..
}
}
I've created a .NET Core Web API that uses SPA with React. I want to preload some data into the application.
My startup.cs file looks like this:
app.UseSpa(spa => {
spa.Options.SourcePath = "ClientApp";
spa.UseSpaPrerendering(options => {
options.BootModulePath = $"main.chunk.js";
options.SupplyData = (context, data) => {
data["siteConfiguration"] = "{my custom object}";
};
});
if (env.IsDevelopment()) {
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
I'm getting an error about the BootModulePath is not being found.
Couldn't find any information about this property used with React or how to pre-render data into React SPA with .NET Core.
Is there an example on how to accomplish this?
Thanks
I'm using a bit of a different approach to accomplish this. I am using spa services in .net core https://learn.microsoft.com/en-us/aspnet/core/client-side/spa-services?view=aspnetcore-2.2#server-prerendering to do my pre rendering. I am also using razor pages to generate the html page (with just a single div for react to mount to). All I need to do is add a tag on my root div in my Index.cshtml page that looks something like this:
<div id="react-app" asp-prerender-module="ClientApp/dist/main-server">Loading...</div>
The entry point for my main-server bundle looks like:
export default createServerRenderer(params => {
//do stuff here
return new Promise<RenderResult>((resolve, reject) => {
params.domainTasks.then(() => {
resolve({
html: /* html string rendered by your app */,
globals: {
cachedVar1: data1,
cachedVar2: data2
}
});
}, reject); // Also propagate any errors back into the host application
});
});
This lets me pre-load data that was created by node during the pre-rendering by putting them in global variables in JavaScript.
If you want to pre-load data that comes from the .net core server and not from node, then what you can do is to pass that data as part of your model to the view.
public async Task<IActionResult> Index()
{
//get data here
return View(preloadedData);
}
Then in the Index.cshtml page, you can add something like this:
<script>
var PRELOADED_CACHE = #Html.Raw(Json.Serialize(#Model));
</script>
This will put a global variable called PRELOADED_CACHE which you can access from your application in the browser (but won't be available during pre-rendering).
I know this isn't precisely what you are looking for, but hopefully this at least gives you some helpful ideas.
So I'm trying to fill a select component with a enum type from mongoose
In my user service the schema looks something like :
firstName: { type:String, required: true },
...
ris:{type: String, default: 'R', enum:['R', 'I', 'S']},
In my feathers service I can access the Model with "this.Model"
so in any hook I can do:
this.Model.schema.path('ris').enumValues); //['R','C','I']
and I get the values from the enum type.
Now since I can't create custom API methods other that the officials ones
Feathers calling custom API method
https://docs.feathersjs.com/clients/readme.html#caveats
https://docs.feathersjs.com/help/faq.html#can-i-expose-custom-service-methods
How can I create a service method/call/something so that I can call it in my
componentDidMount(){ var optns= this.props.getMyEnumsFromFeathers}
and have the enum ['R','C','I'] to setup my dropdown
I'm Using React/Redux/ReduxSaga-FeathersJS
I'd create a service for listing Enums in the find method:
class EnumService {
find(params) {
const { service, path } = params.query;
const values = this.app.service(service).Model.schema.path(path).enumValues;
return Promise.resolve(values);
}
setup(app) {
this.app = app;
}
}
app.use('/enums', new EnumService())
Then on the client you can do
app.service('enums').find({ query: {
service: 'myservice',
path: 'ris'
}
}).then(value => console.log('Got ', values));
I was trying to use this code, but, it does not work like plug and play.
after some play with the app service I figured out the code below
async find(params) {
const { service, path } = params.query;
const values = await this.app.service(service).Model.attributes[path].values;
return values || [];
}
setup(app) {
this.app = app;
}
I am not sure if it is a thing of what database is been used, in my case I am in development environment, so, I am using sqlite.
i'm new to meteor framework
I want to fetch single from the collection
AccountNames = new Mongo.Collection("AccountTypeMaster");
I created a collection using
db.createCollection("AccountTypeMaster")
this.helpers({
AccountNames: () => {
return AccountNames.find({}, {fields: {name: 1}});
}
});
Using above query i'm unable to fetch single field "name" from collection.
I'm now sure what's wrong with my code.
You need to change how you instantiate your collection. The correct Meteor syntax would be:
AccountNames = new Mongo.Collection("AccountTypeMaster");
Helpers also need to be attached to a template. Remember, helpers only run on client-side code.
if (Meteor.isClient) {
// This code only runs on the client
Template.body.helpers({
tasks: function () {
return AccountNames.find({}, { fields: { name: 1 } });
}
});
}
Create Client folder in your project and put client side code into that folder.To create collection in mongodb
Template.name.helpers({
fun: function() {
return AccountNames.find({},{name: 1}).fetch();
})
I am implementing functionality to notify the user of long running job completions using SignalR in an AngularJS application.I have created groups of user based on their name,so for each user a group of his name and different connectionids which he has opened up will be created and he would be notified by his group. I want to notify the user on two pages i.e. landing Page and Job Run Page as even if the user is on landing page and job run completes he should be notified of it.
For the same reason i am creating group by his name on both the pages,so that if he is on any page he would be nofied through the group.
On landing page controller js file i have written code to add the user in group as follow...
$rootScope.signalRHub = $.connection.signalRHub;
$rootScope.hubStart = null;
$rootScope.startHub = function () {
if ($rootScope.hubStart == null)
{
$rootScope.hubStart = $.connection.hub.start();
}
return $rootScope.hubStart;
}
$scope.$on('$locationChangeStart', function (event) {
if ($rootScope.userName != "") {
$rootScope.signalRHub.server.leaveGroup($rootScope.userName);
}
});
// Start the connection
$rootScope.startHub().done(function () {
$rootScope.signalRHub.server.joinGroup($rootScope.userName);
});
on Job Run controller js file i have written following code....
$rootScope.signalRHub.client.showNotification = function (message) {
notify('Your notification message');//notify is the angular js directive injected in this controller which runs fine
};
$scope.$on('$locationChangeStart', function (event) {
$rootScope.signalRHub.server.leaveGroup($rootScope.studyid);
});
// Start the connection
$rootScope.startHub().done(function () {
$rootScope.signalRHub.server.joinGroup($rootScope.userName
});
My Hub File.....
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class SignalRHub : Hub
{
public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}
public Task LeaveGroup(string groupName)
{
return Groups.Remove(Context.ConnectionId, groupName);
}
public void ShowNotification(string jobRunDetailId, string userName)
{
if (!string.IsNullOrEmpty(userName))
{
var context = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>();
context.Clients.Group(userName).showNotification(jobRunDetailId);
}
}
}
The issue is when i run the application the group add functionality for both pages works fine.but when i call "showNotification" from Hub it doesn't show any message.
But strange thing is if i comment the "$rootScope.startHub().done...." function on landing page then the jobrun page notify functionality works fine.I am not sure if writing "$rootScope.startHub().done()..." on two places is creating this problem.please help.
You need to wire up all callbacks before calling start. If you turn client side logging on, it'll tell you what hubs you are subscribed to.
Aside:
[EnableCors] is a webapi specific attribute that does not work in SignalR.