如何订阅返回可观察到的rxjs的类方法?

时间:2019-06-11 23:44:17

标签: javascript rxjs es6-class

我有一个类方法,该类方法使用BehaviorSubject和rxjs中的fromFetch并返回一个可观察的对象。我正在尝试在类之外订阅方法。

我可以console.log获得<form method="POST"> @csrf <!-- Intitulé du thème --> <input type="text" name="intitule" id="intitule" placeholder="Intitulé du thème" required> <br> <!-- Catégorie --> <select name="categorie" required> <option value="">-- Catégorie --</option> <option value="web">Développement web</option> <option value="appMobile">Programmation application mobile</option> <option value="secure">Sécurisation</option> <option value="other">Autre</option> </select> <br> <!-- Filière désirée --> <input type="checkbox" name="filiere[]" id="GL" value="GL" required> <label for="GL">Génie Logiciel</label> <br> <input type="checkbox" name="filiere[]" id="SI" value="SI" required> <label for="SI">Sécurité Informatique</label> <br> <input type="checkbox" name="filiere[]" id="IM" value="IM" required> <label for="IM">Internet et Multimédia</label> <br> <input type="checkbox" name="filiere[]" id="SIRI" value="SIRI" required> <label for="SIRI">Systèmes d'Information et Réseaux Informatiques</label> <br> <!-- Descriptif --> <textarea name="description" id="description" placeholder="Description de la thématique" required></textarea> <br> <input type="submit" name="submit" id="submit" value="Ajouter"> <span id="error-message" class="text-danger"></span> <span id="success-message" class="text-success"></span> </form> 的方法

<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
<script type="text/javascript">
$(() => {
  var itsChecked = null

  $('input[type=checkbox]').on('click', () => {
    if ($('input[type=checkbox]:checked').length > 0) {
      //S'il y a au moins 1 ([...].length > 0) ckecked
      alert('At least one is checked')
      itsChecked = 1
      $('#GL').removeAttr("required")
      $('#SI').removeAttr("required")
      $('#IM').removeAttr("required")
      $('#SIRI').removeAttr("required")
    } else {
      //S'il n'y a aucun checked (!(at least 1)>0)
      alert('None is checked')
      itsChecked = 0
      $('#GL').attr('required', '')
      $('#SI').attr('required', '')
      $('#IM').attr('required', '')
      $('#SIRI').attr('required', '')

    }
  })

  $('#submit').on('click', (e) => {
    e.preventDefault()
    let xhr = new XMLHttpRequest()
    const titre = $('#intitule').val()
    const domaine = $('select[name=categorie]').val()
    let filiereChecked = []

    $.each($("input[type='checkbox']:checked"), (i, elem) => {
      filiereChecked.push($(elem).val())
    })
    const checked = filiereChecked.join(", ")
    const desc = $('#description').val()
    alert(itsChecked)

    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 0)) {
        $('#error-message').html('')
        $('#success-message').fadeIn().html(xhr.responseText)
        setTimeout( () => {
          $('#success-message').fadeOut('slow')
        }, 2000)
        $('form').trigger('reset')
      }
    }
    if (titre === '' || domaine === '' || itsChecked === null || itsChecked === 0 || desc === '') {
      $('#error-message').fadeIn().html('Tous les champs sont requis')
      setTimeout(() => {
        $('#error-message').fadeOut('slow')
      }, 2000)
      xhr.abort()
    } else {
      const url = "{{ route('themes.store') }}"
      const formValues = $("form").serialize()
      xhr.open('POST', url, true)
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
      alert('form sent')
      xhr.send(formValues)
    }
  })
})
</script>

我想像这样调用方法并订阅它

AnonymousSubject {_isScalar: false, observers: Array(0), closed: false, isStopped: false, hasError: false, …}

当我向数据添加export class Client { constructor(opts) { ... } request(operation) { const option$ = new BehaviorSubject(null) const body = JSON.stringify({ query: operation.query, variables: operation.variables }) option$.next(body) return option$.pipe( switchMap(body => { return fromFetch(url, { method: 'POST', body, headers: { 'Content-Type': 'application/json', ...fetchOpts.headers }, ...fetchOpts }).pipe( switchMap(response => { if (response.ok) { // OK return data return response.json() } else { // Server is returning a status requiring the client to try something else. return of({ error: true, message: `Error ${response.status}` }) } }), catchError(err => { // Network or other error, handle appropriately console.error(err) return of({ error: true, message: err.message }) }) ) }) ) } } 时会引发错误:let client = new Client({...}) function handleRequest(operations) { let data = client.request(operations) data.subscribe(...) }

1 个答案:

答案 0 :(得分:1)

问题在于您要返回简单的response.json(),应该从switchMap的of(response.json())块返回类似if (response.ok)的可观察对象-请参见下面的代码-

export class Client {
  constructor(opts) {
    ...
  }
  request(operation) {
    const option$ = new BehaviorSubject(null)
    const body = JSON.stringify({
      query: operation.query,
      variables: operation.variables
    })
    option$.next(body)

    return option$.pipe(
      switchMap(body => {
        return fromFetch(url, {
          method: 'POST',
          body,
          headers: {
            'Content-Type': 'application/json',
            ...fetchOpts.headers
          },
          ...fetchOpts
        }).pipe(
          switchMap(response => {
            if (response.ok) {
              // OK return data
              return of(response.json())
            } else {
              // Server is returning a status requiring the client to try something else.
              return of({
                error: true,
                message: `Error ${response.status}`
              })
            }
          }),
          catchError(err => {
            // Network or other error, handle appropriately
            console.error(err)
            return of({ error: true, message: err.message })
          })
        )
      })
    )
  }
}