dsuryd/dotNetify-Elements

Server Validation doesn't seem to trigger from Component that extends Element

Closed this issue · 2 comments

Hello,

I am try to build a form that integrates with Google ReCaptcha. I want the token returned to become part of the View Model so i can verify it on the server side.

My first implementation was using a standard TextField component, but the value didn't seem to get posted back to the View Model.

So i've instead decided to extend the Element class. Here is the component

import React, { Fragment } from "react";
import PropTypes from "prop-types";
import { Element } from "dotnetify-elements";
import { ReCaptcha as Re } from "react-recaptcha-google";

class ReCaptcha extends Element {
  static propTypes = {
    id: PropTypes.string.isRequired
  };

  componentDidMount() {
    if (this.trialCaptcha) {
      console.log("started, just a second...");
      this.trialCaptcha.reset();
    }
  }

  onLoadRecaptcha = () => {
    if (this.trialCaptcha) {
      this.trialCaptcha.reset();
    }
  };
  verifyCallback = recaptchaToken => {
    // Here you will get the final recaptchaToken!!!
    console.log(recaptchaToken, "<= your recaptcha token");
    this.dispatchProp("ReCaptchaToken", recaptchaToken);
  };

  render() {
    const { fullId, ...props } = this.attrs;
    const src = this.value == null ? "" : this.value;
    console.log("value: " + src);
    return (
      <Fragment>
        <Re
          ref={el => {
            this.trialCaptcha = el;
          }}
          size="small"
          render="explicit"
          sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
          onloadCallback={this.onLoadRecaptcha}
          verifyCallback={this.verifyCallback}
        />
        <input id={fullId} value={src} {...props} onChange={val => {}} />
      </Fragment>
    );
  }
}

export default ReCaptcha;

which seems to work fine posting the value back to the View Model, however the server side validation is never triggered. Also, i did originally use this.dispatch(value), but this didn't seem to update the value at all so i used this.dispatchProp("prop",value) instead.

the corresponding ViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using DotNetify;
using DotNetify.Elements;
using Newtonsoft.Json;

namespace One.Veeam.Web.Model
{
    using LogMagic;
    using Microsoft.Extensions.Configuration;
    using Threading;

    public class NewTrialForm : BaseVM
    {
        public NewTrialForm(IConfiguration config)
        {

            Configuration = config;
    
            // .... other props

            AddProperty<string>("ReCaptchaToken")
                .WithServerValidation(ValidateReCaptchaToken, "Invalid ReCaptcha")
                .WithRequiredValidation();
         
            AddProperty<FormData>("ActivateTrial")
                .SubscribedBy(
                    AddProperty<string>("RequestId", ""), submittedData => Save(submittedData));

        }

        private bool ValidateReCaptchaToken(string token)
        {
             // never hits here
        }

        private string Save(FormData data)
        {
            return Guid.NewGuid().ToString();
        }
    }
}

Is there any reason the ValidateReCaptchaToken method would not get called?

Thanks

When the input tag is replaced with TextField, the server-side validation gets called.

<TextField id={this.props.id} />

seems to work fine! thank you