0
votes

I have a uib-typeahead input.

I need to use a async call to populate it. I´d like to set ng-model to "CODIGO", but I need the viewvalue showing "DESCRICAO". My problem is that after I select a item, ng-model is correct but the viewvalue is not the "DESCRICAO". It is the "CODIGO" as well.

getCBOEspecialidadesByDesc is a async service returning:

[{CODIGO:1, DESCRICAO:'TESTE1'},
{CODIGO:2, DESCRICAO:'TESTE2'},
{CODIGO:3, DESCRICAO:'TESTE3'}
....
]

//controller

$scope.getAllProfissoes=function(val){
    return dataService.getCBOEspecialidadesByDesc(val).then((response)=> {
         return response.data.results
      }, (erro)=> {
        console.log(erro)
      }
  )}

//markup

    <input name="usuarioProfissional.prof" type="text" ng-model="profissional.COD_CBO_3" 
    uib-typeahead="item.CODIGO as item.DESCRICAO for item in getAllProfissoes($viewValue)" 
    typeahead-editable="false" 
    class="form-control">

Mysql tables:

    CREATE TABLE STAFF (
    ID                       BIGINT AUTO_INCREMENT  NOT NULL
    , ATIVO                  BOOLEAN   NOT NULL
    , NOME                   VARCHAR( 100 ) NOT NULL
    , COD_CBO_3              VARCHAR( 10 )
    , CONSTRAINT PK_STAFF_NH
        PRIMARY KEY ( ID )
    )ENGINE=INNODB;


   //used to fill COD_CBO_3  in staff table 
   CREATE TABLE CBO_ESPECIALIDADES (
    ID                          BIGINT AUTO_INCREMENT  NOT NULL
    , CODIGO                    VARCHAR( 10 )
    , DESCRICAO                 VARCHAR( 255 )
    , CONSTRAINT PK_ESPEC_NH
        PRIMARY KEY ( ID )
    )ENGINE=INNODB;

//angular service

angular.module("clinang").service('dataService', ['$http','config', function ($http,config) {

   var urlBase = config.baseUrl;

    this.getCBOEspecialidadesByDesc = function (sel) {
                return $http.get(urlBase+'/cbo_especialidades/ByDesc/'+sel);
            };
}]);

//server router

'use strict';
const express = require('express');
const router = express.Router();

const callback=function(err,data,res){
     console.log(data)
     if (err) return res.status(500).json(err);
     return res.status(200).send(data);
}
//used by getCBOEspecialidadesByDesc angular service
router.get('/ByDesc/:id',function(req,res,next){    
    const searchString=req.params.id||'';
    var params = ['%'+searchString+'%'];
    console.log(params);
    req.getConnection(function (err, connection) {
            var ret
            connection.query('select * from CBO_ESPECIALIDADES where descricao like ?',params, function (error, results, fields) {
              if (error){
                 ret={success:false, results:error}
              }
              else {
               ret={success:true, results:results}
              }
              callback(error,ret,res)
            });
    }); 
});
1

1 Answers

0
votes

This is the way uib-typeahead works.

You can use two tricks to perform what you want.

1) Save the entire object as model

// markup

<input name="usuarioProfissional.prof" type="text" ng-model="profissional.COD_CBO_3" 
    uib-typeahead="item as item.DESCRICAO for item in getAllProfissoes($viewValue)" 
    typeahead-editable="false" 
    class="form-control">

profissional.COD_CBO_3 will contains the whole object. {CODIGO:1, DESCRICAO:'TESTE1'} you have to take it into account when manipulating it.

2) Keep the CODIGO - DESCRICAO mapping and use a formatter

// JS

$scope.formatter = function(model) {
  return $scope.mappings.get(model);
}
$scope.mappings = new Map();
$scope.getAllProfissoes=function(val){
  return dataService.getCBOEspecialidadesByDesc(val).then((response)=> {
       response.data.results.forEach((result) => {$scope.mappings.set(result.CODIGO, result.DESCRICAO);})
       return response.data.results
    }, (erro)=> {
      console.log(erro)
    }
)}

// Markup

<input name="usuarioProfissional.prof" type="text" ng-model="profissional.COD_CBO_3" typeahead-input-formatter="formatter($model)"
    uib-typeahead="item.CODIGO as item.DESCRICAO for item in getAllProfissoes($viewValue)" 
    typeahead-editable="false" 
    class="form-control">

You can view here an example with this solution (Asynchronous results part).

Wich solution to use

The solution depends of your use case. If you need to repopulate the field somewhere (edit form by example) you should consider the first one.

If you don't need to repopulate it you can use the second one.