I am using pnp js to create a list to be used by my sharepoint application. i tried provisioning it using the sharepoint framework schema but i am really have issues with it and have raised an issue for it (https://github.com/SharePoint/sp-dev-docs/issues/1253) . now i am trying to create a list using pnp js as a workaround. my code looks something like this:
pnp.sp.web.lists.ensure("listName").then((ler : ListEnsureResult) => {
listEnsureResults = ler;
if (!ler.created) {
resolve(ler.list);
return Promise.reject(LIST_EXISTS);
}
return ler.list.fields.addText("Field1");
})
i want to add multiple columns but i am always getting an error in adding multiple fields.
You can add multiple fields to list as below in SPFx:
public addFieldsToList(listname: string): Promise<any> {
return Promise.all([
pnp.sp.web.lists.getByTitle(listname).fields.addText("MyField1"),
pnp.sp.web.lists.getByTitle(listname).fields.addText("MyField2"),
pnp.sp.web.lists.getByTitle(listname).fields.addText("MyField3"),
pnp.sp.web.lists.getByTitle(listname).fields.addText("MyField4"),
]).then((response) => {
return response;
}, (error: any) => {
return error;
}).catch((error: any) => {
return error;
});
}
You just need to call this method and pass your list name.
Related
I am trying to get a text from an element with Cypress in the first test from the first domain and then type it in the second test in another domain, here is a code
I have to grab code from h4.
I implemented next part of code:
get studentCouponValue() {
return cy.get('h4').then(($span) => {
const couponValue = $span.text();
cy.log(couponValue);
})
}
in logs, I see the correct coupon's value, but when I am trying to type it into the field I get an error
The chain approach doesn't fit my expectation, cause i am going to use it in different tests.
Try this:
get studentCouponValue() {
return cy.get('h4').then(($span) => {
const couponValue = $span.innerText;
cy.log(couponValue);
})
}
i resolved
initStudentCouponValue() {
const self = this;
return cy.get('main > .container-fluid').find('h4').then((span) => {
self.couponValue = span.text();
cy.log('First log '+ self.couponValue);
return new Cypress.Promise((resolve) => {
return resolve(self.couponValue);
});
});
}
getStudentCouponValue() {
return this.couponValue;
}
in the test where we want to use value
let couponValue;
admin.initStudentCouponValue().then(() => {
couponValue = admin.getStudentCouponValue()
});
and later we can use
coupoValue
for inputs
I’m getting a number of warnings all relating to the use of ‘any’ as a return type for functions in my Typscript code. I am trying to write a node.js backend with Cloud Functions for Firebase, to manage Google Play Billing purchases and subscriptions.
I am following the examples given in the Classy Taxi Server example here:
https://github.com/android/play-billing-samples/tree/main/ClassyTaxiServer
For example, the following:
function purchaseToFirestoreObject(purchase: Purchase, skuType: SkuType): any {
const fObj: any = {};
Object.assign(fObj, purchase);
fObj.formOfPayment = GOOGLE_PLAY_FORM_OF_PAYMENT;
fObj.skuType = skuType;
return fObj;
}
Gives the warning
Unexpected any. Specify a different type. #typescript-eslint/no-explicit-any)
I have tried to change ‘any’ to ‘unknown’, but then I get an error
Property 'formOfPayment' does not exist on type 'unknown'.ts(2339)
and
Property 'skuType' does not exist on type 'unknown'.ts(2339)
In another function
export function mergePurchaseWithFirestorePurchaseRecord(purchase: Purchase, firestoreObject: any) {
// Copy all keys that exist in Firestore but not in Purchase object, to the Purchase object (ex. userID)
Object.keys(firestoreObject).map(key => {
// Skip the internal key-value pairs assigned by convertToFirestorePurchaseRecord()
if ((purchase[key] === undefined) && (FIRESTORE_OBJECT_INTERNAL_KEYS.indexOf(key) === -1)) {
purchase[key] = firestoreObject[key];
}
});
}
I get the following warnings
Missing return type on function. #typescript-eslint/explicit-module-boundary-types
Argument 'firestoreObject' should be typed with a non-any type. #typescript-eslint/explicit-module-boundary-types
Unexpected any. Specify a different type. #typescript-eslint/no-explicit-any
In this function, if I change ‘any’ to ‘unknown’, I still get a warning for
Missing return type on function.
In another example I get an error for the use of ‘any’ in this constructor:
export default class PurchaseManager {
constructor(private purchasesDbRef: CollectionReference, private playDeveloperApiClient: any) { }
And again the warning is
Argument 'playDeveloperApiClient' should be typed with a non-any type. #typescript-eslint/explicit-module-boundary-types
In this case, if I follow the suggestion to use ‘unknown’ instead of ‘any’, then I get an error for ‘purchases’ in the following function:
const apiResponse = await new Promise((resolve, reject) => {
this.playDeveloperApiClient.purchases.products.get({
packageName: packageName,
productId: sku,
token: purchaseToken,
}, (err, result) => {
if (err) {
reject(this.convertPlayAPIErrorToLibraryError(err));
} else {
resolve(result.data);
}
})
});
The error created by changing ‘any’ to ‘unknown’ in the constructor is:
Property 'purchases' does not exist on type 'unknown'.ts(2339)
If I understand correctly, I could prevent all of these (and other similar) warnings without creating errors, by disabling explicit-module-boundary-types, and/or no-explicit-any for the entire file, but I am not sure if this is bad practice?
Is there another (better) way to specify the return types to avoid using ‘any’?
Or is it fine to just go ahead and disable explicit-module-boundary-types or no-explicit-any?
If you do not want to use any, you will have to declare an interface for your type and set that as the return type of the function.
You can do something like:
interface MyType {
formOfPayment: string;
skyType: SkyType;
foo: //<any other pre-existing type>;
}
Then you can use this as the return type of any other function that requires you to return an object with above properties. e.g.
function purchaseToFirestoreObject(purchase: Purchase, skuType: SkuType): MyType {
const fObj: any = {};
Object.assign(fObj, purchase);
fObj.formOfPayment = GOOGLE_PLAY_FORM_OF_PAYMENT;
fObj.skuType = skuType;
return fObj;
}
I need to get an image URL from Contentful entry id.
I am getting such an JSON from Contentful query
{
"sys":{
"space":{
"sys":{
"type":"Link",
"linkType":"Space",
"id":"8v1e7eaw70p2"
}
},
"id":"1JfEwVlD9WmYikE8kS8iCA",
"type":"Entry",
"createdAt":"2018-02-28T18:50:08.758Z",
"updatedAt":"2018-02-28T18:50:08.758Z",
"revision":1,
"contentType":{
"sys":{
"type":"Link",
"linkType":"ContentType",
"id":"image"
}
},
"locale":"en-US"
},
"fields":{
"name":"heat",
"image":{
"sys":{
"type":"Link",
"linkType":"Asset",
"id":"6Inruq2U0M2kOYsSAu8Ywk"
}
}
}
}
I am using JS driver they provide:
client.getEntry()
so how to go thru that link: 6Inruq2U0M2kOYsSAu8Ywk ?
Unfortunately, the js SDK will not be able to resolve links when using the single entry endpoint i.e client.getEntry() because there won't be enough data.
When thing I always recommend to work around this is to use the collection endpoint with a query the desired id as a query param. This way you will always get the desired entry with all it's linked data.
Your code should look something like this
client.getEntries({'sys.id': '6Inruq2U0M2kOYsSAu8Ywk'})
.then(response => console.log(response.items[0].fields.image.fields.file.url))
I hope that helps.
Best,
Khaled
Use client.getEntries({'sys.id': '1JfEwVlD9WmYikE8kS8iCA'})
To get the entry fields and the asset fields.
You can also patch the assets to the fields by running this after fetching the data:
/* Patch all the assets to the fields */
const patchAssets = (fields, assets) => {
Object.keys(fields).forEach(function (key) {
let obj = fields[key];
if (obj.sys && obj.sys.linkType === 'Asset') {
const assetId = obj.sys.id;
const matchAsset = assets.find(asset => {
return asset.id === assetId;
});
obj.file = matchAsset;
}
});
return fields;
};
Another way to get image url is to use getAsset('<asset_id>'). So first, using the getEntry() method, you need to get the entry data, then extract the id from the field: fields.image.sys.id, and pass it to the getAsset method.
In the Office 2013 version of Office Javascript API, I would create a table as follows:
Office.context.document.setSelectedDataAsync(
tbl, {
coercianType: Office.CoercionType.Table,
cellFormat: tableCellFormats,
tableOptions: { filterButton: false }
});
Now with the new way of converting a range to a table, I am missing one thing. That is, how can I create it with the filter buttons off. I don't see a Table.options property where I can set filterbutton = false. (see below snippet):
Excel.run(function (ctx) {
ctx.workbook.tables.add('Sheet1!A1:E7', true);
return ctx.sync();
}).catch(function (error) {
console.log(error);
});
Can someone please post a javascript snippet on how to do this?
Turns out I was able to accomplish this using a binding. The code is as follows. I added a .then() to the Excel.Run so that after the table is created, I can then get add a binding and set the table options:
.then(function (ctx) {
Office.context.document.bindings.
addFromNamedItemAsync('tblRawEmpInfo', Office.BindingType.Table,
{ id: "tblRawEmpInfoBinding" }, function (asyncResult) {
if (asyncResult.status != Office.AsyncResultStatus.Failed) {
Office.select("bindings#tblRawEmpInfoBinding").setTableOptionsAsync({ filterButton: false });
return ctx.sync();
}
else
return ctx.sync();
});
Hopefully this helps someone and I have to say, this javascript api seems like a work in progress. I think a Table.options property should be added, I'll add this comment to the github site.
I need to use a WCF API to save data into a DB. Ordinarily, I'd use chaining, like the example below:
IClientBroker clientBroker = UIContext.CreateWcfInterface<IClientBroker>("Data/ClientBroker.svc");
clientBroker.BeginSetClientBusinessName(_client.ID, businessName, (result) =>
{
_client = ((IClientBroker)result.AsyncState).EndSetClientBusinessName(result);
clientBroker.BeginSetClientAddress(_client.ID, addressObservableCollection, postcodeZip, (result2) =>
{
_client = ((IClientBroker)result2.AsyncState).EndSetClientAddress(result2);
clientBroker.BeginSetClientTelephone(_client.ID, telephone, (result3) =>
{
_client = ((IClientBroker)result3.AsyncState).EndSetClientTelephone(result3);
clientBroker.BeginSetClientFax(_client.ID, fax, (result4) =>
{
_client = ((IClientBroker)result4.AsyncState).EndSetClientFax(result4);
if (customFields.Save(validationSummaryBridge))
{
CloseWindow(true, "ClientID=" + _client.ID.ToString());
}
else
{
validationSummary.Errors.Add(new ValidationSummaryItem("Failed to save Custom Fields"));
}
}, clientBroker);
}, clientBroker);
}, clientBroker);
}, clientBroker);
}
This gives me faux-synchronous behaviour which I need so exceptions are thrown in a timely fashion and I can react on validation events.
This doesn't map well, however, when I have a loop of fields to save. For example, what pattern would be best to save the following list of "Custom Fields", where each Custom Field must be saved using a single WCF call?
ICustomFieldsBroker customFieldsBroker = UIContext.CreateWcfInterface<ICustomFieldsBroker>("Data/CustomFieldsBroker.svc");
foreach (CustomField customField in _customFields)
{
string newValue=_customFieldControlDictionary[customField].CustomField.Value;
customFieldsBroker.BeginSetCustomFieldValueForItem(DataTypeID, DataItemID, customField.Key, newValue, (result) =>
{
((ICustomFieldsBroker)result.AsyncState).EndSetCustomFieldValueForItem(result);
}, customFieldsBroker);
}
In the above example, this would just set off, say, 5 requests to the WCF API/threads which would potentially return AFTER the form has closed. I need them to "line up", so I can list their status and return to the form.
Thanks very much.
Don't let the WCF distract you, but if you have any comments, do let me know. :)
This is the answer I was looking for:
http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2#WCFSilverlightThreadWaiting