Episerver - How to select Items from List<IContent> based on the ContentType - episerver

I have a list of IContent Items, I know that one of the items will be of a particular type.
Currently I am getting this Item with this code:
var result = ancestors.SingleOrDefault(x => x.ContentTypeID == 104);
I know the name of MyType how can do this without an hard coded Id?
If this number is diffrent in mulitiple enviorments the code will fail, can anyone show me how to do this?

You should be able to just type-check it like:
var result = ancestors.SingleOrDefault(x => x is MyContentType);
Or:
var result = ancestors.OfType<MyContentType>();
Unless I'm misunderstanding your question?

Related

possible to update a property after new model is created in sailsjs?

I am trying to create a new record for a model and there are fields I need to save later after the model is created.
I have the code like this
let new_model = await Model.create({ name, type}).fetch();
new_model.content = 'abc';
new_model.save();
TypeError: new_model.save is not a function
I googled, it doesn't seem like sailsjs can be done this way so I guess I have to use the update or updateOne by sails. But the thing is, name,type fields are not unique and will not be so using update will actually turn into update for ALL records. updateOne will give me errors saying there's more than one record though
Does anyone has any suggestions on what can be done here?
One other option I can think of is doing something like this with updateOne
let new_model = await Model.create({ name, type}).fetch();
// getting your content here or do something else
const content = 'abc';
new_model = await Model.updateOne({ id:new_model.id}).set({content});

Pre-fill with the id of an entity

How can I pre-fill a new content with an entity relationship that I know the id? I know the item is, let's say 1234, but if I use this number like that :
#Edit.Toolbar(actions: "new", contentType: "NewsItem", prefill = new { Category = 1234 } )
It doesn't work. When I implement the code above, the form for a new item shows up but instead of having the correct item selected, I have (item not found). Obviously, my argument is not correct. So, how do I code this argument?
I also tried
Category = {1234}
Category = new {(1234}}
Category = "1234"
But nothing works. Any ideas?
We're working on enhancing this, but as of now, you are best off using the guid - as shown in the wiki: https://github.com/2sic/2sxc/wiki/razor-edit.toolbar#multiple-entities-prefil

How to Fetch a set of Specific Keys in Firebase?

Say I'd like to fetch only items that contains keys: "-Ju2-oZ8sJIES8_shkTv", "-Ju2-zGVMuX9tMGfySko", and "-Ju202XUwybotkDPloeo".
var items = new Firebase("https://hello-cambodia.firebaseio.com/items");
items.orderByKey().equalTo("-Ju2-gVQbXNgxMlojo-T").once('value', function(snap1){
items.orderByKey().equalTo("-Ju2-zGVMuX9tMGfySko").once('value', function(snap2){
items.orderByKey().equalTo("-Ju202XUwybotkDPloeo").once('value', function(snap3){
console.log(snap1.val());
console.log(snap2.val());
console.log(snap3.val());
})
})
});
I don't feel that this is the right way to fetch the items, especially, when I have 1000 keys over to fetch from.
If possible, I really hope for something where I can give a set of array
like
var itemKeys = ["-Ju2-gVQbXNgxMlojo-T","-Ju2-zGVMuX9tMGfySko", "-Ju202XUwybotkDPloeo"];
var items = new Firebase("https://hello-cambodia.firebaseio.com/items");
items.orderByKey().equalTo(itemKeys).once('value', function(snap){
console.log(snap.val());
});
Any suggestions would be appreciated.
Thanks
Doing this:
items.orderByKey().equalTo("-Ju2-gVQbXNgxMlojo-T")
Gives exactly the same result as:
items.child("-Ju2-gVQbXNgxMlojo-T")
But the latter is not only more readable, it will also prevent the need for scanning indexes.
But what you have to answer is why want to select these three items? Is it because they all have the same status? Because they fell into a specific date range? Because the user selected them in a list? As soon as you can identify the reason for selecting these three items, you can look to convert the selection into a query. E.g.
var recentItems = ref.orderByChild("createdTimestamp")
.startAt(Date.now() - 24*60*60*1000)
.endAt(Date.now());
recentItems.on('child_added'...
This query would give you the items of the past day, if you had a field with the timestamp.
You can use Firebase child. For example,
var currFirebaseRoom = new Firebase(yourFirebaseURL)
var userRef = currFirebaseRoom.child('users');
Now you can access this child with
userRef.on('value', function(userSnapshot) {
//your code
}
You generally should not be access things using the Firebase keys. Create a child called data and put all your values there and then you can access them through that child reference.

angular.js using highcharts-ng not maintaining series order, unless I force $apply (which throws already in progress error)

This may be unfixable, but I was hoping someone may have come across this before and found a workaround.
Highcharts-ng seems to merge series data with existing data in such a way that I cannot maintain the ordering of series. I specifically want to show two series, call them A & B, from left to right (because the form controls are organized that way).
So, I'm starting with a series A, then I add a B, then change A, and it's now in the order B & A.
I've looked at the highcharts-ng code, and I can understand why it's happening (see processSeries method below).
The only workaround that I've been able to get to work is to completely reset the series data and call $apply, which of course you cannot do in the middle of another apply.
$scope.chartConfig.series.length = 0
$scope.chartConfig.xAxis.categories.length = 0
$scope.$apply(); # force update with empty series (throws $apply already in progress error)
I'd really like to know if there's an option that I can set, or some other workaround that would allow me to use this how I'd like without having to resort to editing the directive.
var processSeries = function(chart, series) {
var ids = []
if(series) {
ensureIds(series);
//Find series to add or update
series.forEach(function (s) {
ids.push(s.id)
var chartSeries = chart.get(s.id);
if (chartSeries) {
chartSeries.update(angular.copy(s), false);
} else {
chart.addSeries(angular.copy(s), false)
}
});
}
Thanks a bunch!
Answering my own question. It seems the workaround is to have placeholders for the series in fixed positions, and do updates rather than replacements, such as:
$scope.chartConfig.series[0].data = [1,2,3]
$scope.chartConfig.series[0].name = 'foo'
$scope.chartConfig.series[1].data = [4,5,6]
$scope.chartConfig.series[1].name = 'bar'
Even doing something like:
$scope.chartConfig.series[0] = {name: 'foo', data: [1,2,3]}
$scope.chartConfig.series[1] = {name: 'bar', data: [4,5,6]}
results in the ordering issue described above.

Creating an array of SelectOption Lists

Im trying to set up an online test, using a visualforce page that pulls data from 3 objects in salesforce COPE_Tests__C, COPE_Questions__C, and COPE_Options__c. Once the user selects the specific test, I thought I would be able to make a call like this to get all the other data:
questions = [select id, name, question_body__c,
(select id, name, option_body__c from COPE_options__r order by name ASC)
from COPE_questions__c where COPE_test__c = :tid];
And then use apex:repeat and apex:selectRadio/apex:selectOption to generate the actual test form. But for some reason it would not render the radioboxes. So it would seem I need to create selectOption lists and then use apex:selectOptions. But im not sure how to set this up . How can I have it create a public list<selectOption> automatically for each question?
Is there a way to set up an array of list<selectOption>?
I don't know about creating it automatically but going over your question object in a loop should be pretty easy, something over the lines of
List<List<SelectOption> options = new List<List<SelectOption>;
for(COPE_Questions__C q : questions){
List<SelectOption> list = new List<SelectOption>();
for(COPE_options__r op : q.COPE_options__r){
list.add(new SelectOption(op.id, op.option_body__c);
}
options.add(list);
}
Hope it helps.

Resources