Is this possible to show a user defined message in package manager console while running a Seed method or throwing any exceptions?
When i am getting below error message from package manager console when throwing exception while running Seed method from Packager manager console my running Seed method has been stopped and not able to process for other seed methods! so I used Try-Catch block to skip those exception and continue other seed methods.
Object reference not set to an instance of an object.
My Seed Methods Seems like this:
context.Subjects.AddOrUpdate(MyRepository.SeedSubject.Subject());
BookTypes
context.BookTypes.AddOrUpdate(b => b.Type,
new BookType { Type = "Audio" },
new BookType { Type = "Book" },
new BookType { Type = "Video" }
);
Books
context.Books.AddOrUpdate(FCA.Repository.SeedBook.Books());
try
{
context.BookSubjects.AddOrUpdate(b => b.BookSubjectID,
new BookSubject { SubjectID = context.Subjects.SingleOrDefault(s => s.Name == "Graduation").SubjectID, BookID = context.Books.SingleOrDefault(b => b.Title == "Graduation Event").BookID },
new BookSubject { SubjectID = context.Subjects.SingleOrDefault(s => s.Name == "Online Courses").SubjectID, BookID = context.Books.SingleOrDefault(b => b.Title == "3rd Grade Online Complete Set").BookID },
new BookSubject { SubjectID = context.Subjects.SingleOrDefault(s => s.Name == "8th Grade").SubjectID, BookID = context.Books.SingleOrDefault(b => b.Title == "Access 2000 Set Lifepac").BookID });
}
catch (Exception ex)
{
//How to display this message in Package Manager Console while running Seed method?
}
How can i show user defined messages in package manager console Or Is this possible to run Seed method with Break-Point?
Related
I have an shopware6 admin extension where some custom entity is stored and loaded. This custom entity has a ManyToManyAssociation to another custom entity. In my mask I use a entity multi select component for the selection.
const category = this.categoryRepository.create();
category.categoryId = this.newCategory;
category.weight = this.newWeight;
category.certificates = this.certificateCollection;
this.categoryRepository.save(category).then(() => {
this.isLoading = false;
this.isSaveSuccessful = true;
this.getList();
}).catch((exception) => {
this.isLoading = false;
this.createNotificationError({
message: this.$tc(
'global.notification.notificationSaveErrorMessageRequiredFieldsInvalid'
)
});
throw exception;
});
<sw-entity-multi-select
:label-property="labelPropertyCertificate"
:criteria="certificateCriteria"
entity-name="certificate"
:entity-collection="certificateCollection"
#change="changeCertificates"
/>
When sending the save request the content of my certificate selection is send with and js object with the property id. To create the correct entity I added some Entity creation process and build my own entity collection for the categoryCertificate collection.
Like this
const category = this.categoryRepository.create();
category.categoryId = this.newCategory;
category.weight = this.newWeight;
category.certificates = new EntityCollection(
this.categoryCertificateRepository.route,
this.categoryCertificateRepository.entityName,
Context.api,
);
this.certificates.forEach(function(item){
const categoryCertificate = me.categoryCertificateRepository.create();
categoryCertificate.categoryId = category.id;
categoryCertificate.certificateId = item.id;
category.certificates.add(categoryCertificate);
});
console.log(category);
this.categoryRepository.save(category).then(() => {
this.isLoading = false;
this.isSaveSuccessful = true;
this.getList();
}).catch((exception) => {
this.isLoading = false;
this.createNotificationError({
message: this.$tc(
'global.notification.notificationSaveErrorMessageRequiredFieldsInvalid'
)
});
throw exception;
});
The console.log shows this, which would be correct
categoryId: "77b959cf66de4c1590c7f9b7da3982f3"
certificates: r(1)
0: Proxy
[[Handler]]: Object
[[Target]]: Object
categoryId: "aa26daab83b04cc6af9a525e7ec1ce16"
certificateId: "8c32fb76000844bcb4d850831fe2f6c1"
extensions: {}
_isNew: true
[[Prototype]]: Object
[[IsRevoked]]: false
...
The request payload shows this, which is not correct.
{id: "b96c923dcee941c7a05c0cb4f98de4d9", categoryId: "251448b91bc742de85643f5fccd89051", weight: 0,…}
categoryId: "251448b91bc742de85643f5fccd89051"
certificates: [{id: "10fb19bccdb0419ca5f4b7abe6561db2"}]
id: "b96c923dcee941c7a05c0cb4f98de4d9"
weight: 0
where are my categoryId & certificateId properties gone? Does the categoryRepository strip them out?
Edit solution
Thx to dneustadt
this.certificates.forEach(function(item){
const categoryCertificate = me.careHintCategoryCertificateRepository.create();
categoryCertificate.id = item.id;
category.certificates.add(categoryCertificate);
});
this works!
By using a ManyToManyAssociationField the values for the columns of the mapping table are resolved dynamically. Since these columns belong to the mapping definition, not to your actual CategoryCertificate entity, they get stripped. You don't need to provide these IDs when you use the respective ManyToManyAssociationField property to assign data from either side.
My code has a simple card carousel which has action button like below:
actions = [
{
"type": "Action.Submit",
"title": "Qualify",
"data": { "action" : "qualify_lead" }
},
{
"type": "Action.OpenUrl",
"title": "Retire",
"url": "{viewUrl}"
},
{
"type": "Action.ShowCard",
"title": "Add Note",
"card": this.noteCard(item.LeadId, "leads")
}
]
I am having a method to handle qualify_lead action like below
async qualifyLead(context:any){
console.log("in qualifyLead:" + JSON.stringify(context.activity))
await context.updateActivity(this.successCard('Lead is qualified'))
}
All I am doing on purpose is to replace entire carousel with a simple text message. But it fails with error:
Error: BotFrameworkAdapter.updateActivity(): missing activity.id
Where do i get this ?
I am using google firebase for this and the wrapper code is like below
const {
TurnContext,
TeamsActivityHandler,
CardFactory,
AttachmentLayoutTypes,
ActionTypes
} = require('botbuilder');
class TeamsConversationBot extends TeamsActivityHandler {
constructor() {
super();
this.leadState =
this.conversationState.createProperty('leadCarouselState');
this.onMessage(async (context:any, next:any) => {
TurnContext.removeRecipientMention(context.activity);
let msg = context.activity.text
const action = context.activity.value
let objNum = ''
let keyword = ''
if(msg === undefined && action === undefined)
msg = 'help'
else if(msg !== undefined){
msg = msg.trim().toLowerCase()
if(msg.indexOf("help") > -1)
msg = 'help'
else{
if(msg.startsWith('lead')){
msg = 'lead'
}
}
}
switch (msg) {
case 'lead':
await this.lead(context, userKey, platform)
break;
case 'qualify_lead':
await this.qualifyLead(context)
break;
}
await next();
});
}
I'm not sure exactly what this.successCard('Lead is qualified') does, but presumably it returns an Activity. To my knowledge, in order for this Activity to replace another one, you need to set it's Id property to match the previous message. That means that, when you send the previous message (i.e. the card), you need to capture the reference that's returned from the send method on the context (e.g. into bot state), and then use it for this new activity.
As I explained in my answer to your other question, you need to save the activity ID in bot state and then apply it to the update that you're sending. The Bot Framework can't update an activity unless you tell it which activity to update, and you do that using an activity ID.
This was the part that saves the ID:
const dict = await this.carouselState.get(turnContext, {});
dict[batchId] = {
[KEYACTIVITYID]: response.id,
[KEYLEADS]: leads
};
And this was the part that applies it to the updated activity:
const update = this.createCarousel(batchId, leads);
update.id = info[KEYACTIVITYID];
I am wondering if it is possible to fetch a job by requisitionId in Google Cloud Talent Solution. requisitionId has to be unique across jobs so it seems like a natural candidate for looking a job up.
When a job is created the api returns a job name that can be used to look the job up:
You can retrieve the details of a previously inserted job by sending a GET request to the Cloud Talent Solution. The URI should include the previously inserted job name returned by the original create request, as a URL parameter.
I'd like to avoid storing these names if possible. In my view storing them adds unnecessary complexity since I already have a unique requisitionId. To be clear the API does not let you add jobs with a duplicate requisitionId:
Job projects/{my_app_id}/jobs/{google_assigned_id} already exists. Request ID for tracking: ... Related Job requisition ID: ...
So can I look up jobs by requisitionId?
I could parse the error message that's returned to get the job name..but that seems pretty brittle.
It turns out the list method takes requisitionId so for a full, read-create-update cycle we can do:
const listRequest = {
parent: `projects/${projectId}`,
'filter': `companyName="${companyName}" AND requisitionId="${requisitionId}"`
}
const listResult = await jobService.projects.jobs.list(listRequest)
const existingJobs = listResult.data.jobs || [];
let existingJob = null
if (existingJobs && existingJobs.length > 0) {
existingJob = existingJobs[0]
}
let googleJob
if (!existingJob) {
const createRequest = {
'parent': `projects/${projectId}`,
'resource': {
'job': {
companyName,
requisitionId,
title,
description,
applicationInfo: {
emails: ['email#example.com']
}
}
}
}
googleJob = await jobService.projects.jobs.create(createRequest)
.then(result => result)
.catch(resp => {
console.error("ERROR")
console.error(resp)
})
} else {
const patchRequest = {
'name': existingJob.name,
'resource': {
'job': {
companyName,
requisitionId,
title,
description,
applicationInfo: {
emails: ['email#example.com']
}
}
}
}
googleJob = await jobService.projects.jobs.patch(patchRequest)
.then(result => result)
.catch(resp => {
console.error("ERROR")
console.error(resp)
})
}
Docs: https://cloud.google.com/talent-solution/job-search/docs/reference/rest/v3/projects.jobs/list?authuser=0&hl=de
Notes:
The double quotes in the filter parameter are important. It will not accept single quotes and will give a cryptic error message.
The patch request cannot take a parent parameter even though everything else requires a parent parameter...
one can add it as custom attribute:
Map<String, CustomAttribute> attributes = new HashMap<>();
attributes
.put("requisitionId", new CustomAttribute().setStringValue(requisitionId)
.setFilterable(true));
Job job = new Job()
...
.setCustomAttributes(attributes);
Job jobCreated = createJob(job);
String jobName = jobCreated.getName();
and then search for requisitionId with a custom attribute filter:
JobQuery jobQuery = new JobQuery().setCustomAttributeFilter(filter);
this is a little redundant, but JobQuery has no method .setRequisitionId().
here's the documentation.
I'm trying to encapsulate a TextInput such that when the value changes it does a serverside lookup and based on the result shows a notification to the user: "That group name already exists". I've been using this as my example to start from: https://marmelab.com/admin-on-rest/Actions.html#the-simple-way
My current error is
Error: The TextInput component wasn't called within a redux-form . Did you decorate it and forget to add the addField prop to your component? See https://marmelab.com/admin-on-rest/Inputs.html#writing-your-own-input-component for details.
but even if I add in
NameLookupTextInput.defaultProps = {
addField: true, // require a <Field> decoration
}
I still get the error. Heres my code
class NameLookupTextInput extends TextInput {
handleChange = eventOrValue => {
console.log("handleChange",eventOrValue);
this.props.onChange(eventOrValue);
this.props.input.onChange(eventOrValue);
if(this.timeoutHandle){
clearTimeout(this.timeoutHandle);
}
console.log(fetch);
this.timeoutHandle = setTimeout(function(){
let value = this.props.input.value;
fetchUtils.fetchJson(API_ENDPOINT+'/groupNameCheck/'+value, { method: 'GET'})
.then((data) => {
console.log(data);
let exists = data.json.exists;
let name = data.json.name;
if(exists){
console.log(this.props.showNotification('The group name "'+name+'" already exists.'));
}else{
console.log(this.props.showNotification('The group name "'+name+'" does not exist.'));
}
})
.catch((e) => {
console.error(e);
//showNotification('Error: comment not approved', 'warning')
});
}.bind(this),500);
};
}
export default connect(null, {
showNotification: showNotificationAction
})(NameLookupTextInput);
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