Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Heather Floyd 610 posts 1033 karma points MVP 6x c-trib
    Jun 03, 2022 @ 16:44
    Heather Floyd
    0

    Umbraco Forms - Create custom FieldPreValueSourceType using picked Content node

    I am attempting to create a custom prevalue source - but I am looking to get data from a property on the node, rather than using children nodes as the source of the prevalues.

    Here is what I have so far:

       using System;
        using System.Collections.Generic;
        using Microsoft.Extensions.Logging;
        using Rwater.Services;
        using Umbraco.Cms.Core;
        using Umbraco.Forms.Core;
        using Umbraco.Forms.Core.Models;
    
        public class FormPrevaluesSourceNode : FieldPreValueSourceType
        {
            private readonly ILogger _logger;
            private readonly IPublishedContentQuery _publishedContentQuery;
    
            [Umbraco.Forms.Core.Attributes.Setting(name: "Form Prevalues Source Node",
                Alias = "SourceNodeId",
                Description = "Node holding the Options desired.",
                View = "pickers.content")]
            public int SourceNodeId { get; set; }
    
            public FormPrevaluesSourceNode(IPublishedContentQuery publishedContentQuery,
                ILogger<FormPrevaluesSourceNode> logger)
            {
                _logger = logger;
                _publishedContentQuery = publishedContentQuery;
    
                this.Id = new Guid("0E4D4E2B-56E1-4E86-84E4-9A0A6051B57C");
                this.Name = "Content-defined Form Prevalues Source Node";
                this.Description = "Select a node of type 'FormPrevaluesSourceNode'";
                this.Group = "Custom";
                this.Icon = "icon-science";
            }
    
    
            public override List<PreValue> GetPreValues(Field field, Form form)
            {
    
    
                List<PreValue> result = new List<PreValue>();
    
                try
                {
                    var node = _publishedContentQuery.Content(SourceNodeId);
                    if (node != null)
                    {
                        int sort = 0;
                        var preValSource = new Models.FormPrevaluesSourceNode(node, null);
    
                        foreach (var prevalue in preValSource.PreValues)
                        {
                            PreValue pv = new PreValue();
                            pv.Id = sort == 0 ? SourceNodeId : sort;
                            pv.Value = prevalue.StoredValue;
                            pv.SortOrder = sort;
                            result.Add(pv);
                            sort++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Unable to get options from FormPrevaluesSourceNode #{SourceNodeId}", ex);
                }
    
                return result;
            }
    
            public override List<Exception> ValidateSettings()
            {
                List<Exception> exs = new List<Exception>();
    
                if (SourceNodeId == default(int))
                    exs.Add(new Exception("'SourceNodeId' setting not filled out’"));
    
                return exs;
            }
        }
    

    and

       public class FormsComposer : IComposer
        {
            public void Compose(IUmbracoBuilder builder)
            {
                builder.WithCollectionBuilder<FieldPreValueSourceCollectionBuilder>()
                    .Add<FormPrevaluesSourceNode>();
            }
        }
    

    But when I compile, I am getting this error:

    Cannot consume scoped service 'Umbraco.Cms.Core.IPublishedContentQuery' from singleton 'MyNamespace.FormPrevaluesSourceNode'.)
    

    Is there a singleton-accessible way to get an IPublishedContent from the int Node Id returned from the Setting?

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Jun 03, 2022 @ 16:58
    Andy Butland
    1

    Hi Heather - I think in this context you need to inject IPublishedContentQueryAccessor, which can be injected into singletons, and from there you have a method available TryGetValue that you can use to get an instance of IPublishedContentQuery.

    Hope that helps.

    Andy

  • Heather Floyd 610 posts 1033 karma points MVP 6x c-trib
    Jun 03, 2022 @ 17:24
    Heather Floyd
    0

    Thanks, Andy,

    Do you know if there is a preference between using IPublishedContentQuery or using UmbracoContextFactory ?

    example:

    using (var umbracoContextReference = _UmbracoContextFactory.EnsureUmbracoContext())
                            {
                                iPub = umbracoContextReference.UmbracoContext.Content.GetById(nodeId);
                            }
    
  • Emma Garland 41 posts 123 karma points MVP 7x c-trib
    Dec 06, 2022 @ 20:58
    Emma Garland
    0

    This helped me with a dependency injection scoping struggle, thanks!

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Jun 06, 2022 @ 06:19
    Andy Butland
    0

    No, not sure, but I don't think there'd be any fundamental difference here (i.e. in the end you'd get the same object back to query against).

  • Heather Floyd 610 posts 1033 karma points MVP 6x c-trib
    Jun 06, 2022 @ 16:27
    Heather Floyd
    0

    I was just wondering if one or the other was more performant, or more stable, etc.

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies