0

I get objects of the type of:

{

    personalData: {


                    name:   "Diego",
                    last:   "Aguilar",
                    mail:   "diego@domain.com"
    },

    professionalData: {

                    almaMater:  "BUAP",
                    courses: [

                        {},
                        {
                            name:   "JavaScript Newbies",
                            tags:   ["","",""]
                        }
                    ]
    }
}

So in that example, empty objects at professionalData.courses should be dropped and so the tags key at second object as their array elements are whole empty ones.

In general words, any time I find values being an empty object or array element, drop them. Also, if a key would get empty arrays or objects, drop them too.

Maybe jQuery or lodash/underscore would give a direct solution to this?

This is an example of an object stored at MongoDB:

{
    "_id" : ObjectId("537e09c9896e05225cf50cb8"),
    "datosPersonales" : {
        "name" : "Maricela",
        "lastname" : "Aguilar Flores",
        "age" : "22",
        "phone" : "2878710097",
        "mobile" : "2878812505",
        "email" : "af05_@hotmail.com",
        "address" : "Carranza 168 Int 2"
    },
    "datosProfesionales" : {
        "postgraduates" : [
            {
                "degree" : "Especialidad",
                "title" : "Amor",
                "cedula" : "ASFAS5"
            },
            {
                "degree" : "Maestría",
                "title" : "Romance",
                "cedula" : "v"
            }
        ],
        "works" : [
            "Universidad Hispano"
        ],
        "freelances" : [ ],
        "noPsychoWorks" : [ ],
        "almaMater" : "BUAP",
        "course" : "1987",
        "cedula" : "SAFS555FSA",
        "workAreas" : [
            "Clínica",
            "Laboral"
        ],
        "freelance" : "true",
        "noPsychoWork" : "false"
    },
    "interesesProfesionales" : {
        "groups" : [
            "Asociación de Psicólogos de Tuxtepec",
            "Club de Toby"
        ],
        "trainingTopics" : [
            "Real Madrid",
            "Cocina"
        ],
        "belongsToSomewhere" : "true",
        "activities" : [
            "Conferencias y encuentros",
            "Talleres"
        ],
        "trainingAreas" : [
            "Educativa"
        ],
        "hasParticipated" : "true",
        "wantsToBelong" : "true",
        "whyToBelong" : "Futuro"
    }
}

EDIT

This ugly objects are result of a bad handling in my Angular module. That object came as a result of this code at Angular controller:

(function() {


var app = angular.module('PsicologosRegister', ['checklist-model'])

app.controller('PsicologoController', function($scope) {

    this.psycho = psicologo

    this.print = function() {

        console.log(this.psycho)
    }

    this.toMongo = function() {
        $.ajax({
            type:"POST",
            url:"/psychos",
            data:this.psycho        
        })              
    }
})

app.controller('PersonalDataController', function() {

    this.data = datos_Personales

})

app.controller('ProfessionalDataController', function() {

    this.data = datos_Profesionales
})

app.controller('ProfessionalInterestsController', function() {

    this.data = intereses_Profesionales

    this.print = function() {

        console.log(this.psycho)
    }
})              

app.controller('PosgraduateController', function() {


    this.degrees = [

                    'Especialidad',
                    'Maestría',
                    'Doctorado'
    ]

    this.postgraduates = _postgraduates

    this.addPostgraduate = function() {

        this.postgraduates.push({})
    }



})

app.controller('WorkController', function() {

    this.works = _works

    this.addWork = function() {

        this.works.push("")
    }
})      

app.controller('FreelanceController', function() {

    this.freelances = _freelances

    this.addFreelance = function() {

        this.freelances.push("")
    }

    this.noFreelance = function() {
        this.freelances = [""]
    }
})          

app.controller('NoPsychoWorkController', function() {

    this.noPsychoWorks = _noPsychoWorks

    this.addNoPsychoWork = function() {

        this.noPsychoWorks.push("")
    }

    this.notNoPsychoWorks = function() {
        this.noPsychoWorks = [""]
    }           
})  

app.controller('TrainingTopicsController', function() {

    this.trainingTopics = _trainingTopics
    this.add = function() {
        this.trainingTopics.push("")
    }
})

app.controller('GroupsController', function() {

    this.groups = _groups

    this.add = function() {
        this.groups.push("")
    }

    this.doesntBelongToAnywhere = function() {
        this.groups = [""]
    }
})      

var _noPsychoWorks = [""]
var _freelances = [""]
var _works = [""]
var _postgraduates = [{}]
var _trainingTopics = [""]
var _groups = [""]
var _events = [{}]
var datos_Personales = {}
var datos_Profesionales = {postgraduates:_postgraduates, works: _works, freelances:_freelances, noPsychoWorks:_noPsychoWorks}
var intereses_Profesionales = {events:_events,groups:_groups,trainingTopics:_trainingTopics}

var psicologo = {

                    datosPersonales:            datos_Personales,
                    datosProfesionales:         datos_Profesionales,
                    interesesProfesionales:     intereses_Profesionales
}
})()

This data is generated with the inputs from a web form, rendered with Angular. For elements at arrays I use ng-repeat. The problem is that as it's unknown whether there will be any freelances, postgraduates, etc. I start their belonging keys with Strings, for example.

This is my whole long markup:

<div id="formulario">

    <div class="container" id="seccionRegistro1" ng-controller="PersonalDataController as personal">
        <form class="form-horizontal" role="form">

            <div class="form-group">
                <label for="inputNombre" class="col-xs-2 control-label">Nombre(s)</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Nombre(s)" ng-model="personal.data.name" >

                </div>
            </div>

            <div class="form-group">
                <label for="inputApellidos" class="col-xs-2 control-label">Apellidos</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Apellidos" ng-model="personal.data.lastname">
                </div>
            </div>

            <div class="form-group">
                <label for="inputEdad" class="col-xs-2 control-label">Edad</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Edad" ng-model="personal.data.age">
                </div>
            </div>

            <div class="form-group">
                <label for="inputTel" class="col-xs-2 control-label">Teléfono</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Teléfono" ng-model="personal.data.phone">
                </div>
            </div>

            <div class="form-group">
                <label for="inputCel" class="col-xs-2 control-label">Celular</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Celular" ng-model="personal.data.mobile">
                </div>
            </div>

            <div class="form-group">
                <label for="inputMail" class="col-xs-2 control-label">e-mail</label>
                <div class="col-xs-10">
                  <input type="email" class="form-control" placeholder="e-mail" ng-model="personal.data.email">
                </div>
            </div>  

            <div class="form-group">
                <label for="inputFB" class="col-xs-2 control-label">Facebook</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Facebook" ng-model="personal.data.fb">
                </div>
            </div>

            <div class="form-group">
                <label for="inputDireccion" class="col-xs-2 control-label">Dirección</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Dirección" ng-model="personal.data.address">
                </div>
            </div>                                            

            <div class="col-xs-offset-2 col-xs-10">
                <input type="button" class="btn btn-primary btnSeccion" id="btnSeccion1" value="Continuar"/>
            </div>

        </form>
    </div>

    <div class="container" id="seccionRegistro2" ng-controller="ProfessionalDataController as professional">
        <form class="form-horizontal" role="form">

            <div class="form-group">
                <label for="inputAlmaMater" class="col-xs-2 control-label">Egresado de</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Egresado de" ng-model="professional.data.almaMater">
                </div>
            </div>              

            <div class="form-group">
                <label for="inputAñoEgreso" class="col-xs-2 control-label">Año de egreso</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Año de egreso" ng-model="professional.data.course">
                </div>
            </div>

            <div class="form-group">
                <label for="inputCedula" class="col-xs-2 control-label">Cédula Profesional</label>
                <div class="col-xs-10">
                  <input type="text" class="form-control" placeholder="Cédula Profesional" ng-model="professional.data.cedula">
                </div>
            </div>

            <div class="form-group" ng-controller="PosgraduateController as postgraduate">
                <label for="checkPosgrado" class="col-xs-2 control-label">Estudios de Posgrado</label>
                <div ng-repeat="p in postgraduate.postgraduates track by $index">
                    <div class="padding-between-lines">
                    <label for="checkPosgrado" class="col-xs-2 control-label" ng-show="$index!=0"></label>                          
                    <div class="col-xs-2">
                        <select ng-options="t for t in postgraduate.degrees" ng-model="p.degree" class="form-control"><select>              
                    </div>

                    <div class="col-xs-4">
                        <input type="text" ng-model="p.title" class="form-control inputPosgradoTitulo" placeholder="Título">                        
                    </div>

                    <div class="col-xs-3">
                        <input type="text" ng-model="p.cedula" class="form-control inputPosgradoCedula" placeholder="Cédula">
                    </div>                              

                    <div class="col-xs-1">
                            <input type="button" class="form-control" value="Añadir" ng-click="postgraduate.addPostgraduate()" ng-show="$index==0">
                    </div>
                    </div>
                </div>

            </div>

            <div class="form-group">
                <label for="areaTrabajo" class="col-xs-2 control-label">Areas de la psicología en las que se desempeña</label>

                <div class="col-xs-10" >
                    <label class="checkbox-inline" ng-repeat="area in ['Clínica', 'Social', 'Laboral', 'Educativa']">
                    <input type="checkbox" checklist-model="professional.data.workAreas" checklist-value="area"> {{area}}
                    </label>    
                </div>
            </div>

            <div class="form-group" ng-controller="WorkController as work">
                <label for="inputTrabajo" class="col-xs-2 control-label">Institución de trabajo</label>
                <div ng-repeat="w in work.works track by $index">
                <div class="padding-between-lines">
                    <label for="inputTrabajo" class="col-xs-2 control-label" ng-show="$index!=0"></label>
                    <div class="col-xs-9">
                        <input type="text" class="form-control" placeholder="Institución de trabajo" ng-model="work.works[$index]">
                    </div>
                    <div class="col-xs-1">
                        <input type="button" class="form-control" value="Añadir" ng-click="work.addWork()" ng-show="$index==0">
                    </div>                          
                </div>
                </div>

            </div>


            <div class="form-group" ng-controller="FreelanceController as freelance">

                <label for="trabajoIndependiente" class="col-xs-2 control-label">Desarrollo Profesional Independiente</label>

                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" ng-model="professional.data.freelance" name="optionsTrabajoIndependiente" value="true">
                        Sí
                      </label>
                    </div>
                </div>
                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" ng-model="professional.data.freelance" ng-change="freelance.noFreelance()" name="optionsTrabajoIndependiente" value="false">
                        No
                      </label>
                    </div>
                </div>                  

                <div ng-repeat="f in freelance.freelances track by $index">
                <div class="padding-between-lines">
                    <label class="col-xs-4" ng-hide="$index==0"></label>
                    <div class="col-xs-7">
                        <input type="text" class="form-control" placeholder="Desarrollo profesional independiente" ng-model="freelance.freelances[$index]" ng-disabled="professional.data.freelance=='false'">
                    </div>

                    <div class="col-xs-1">
                        <input type="button" class="form-control añadirTrabajoIndependiente" value="Añadir" ng-show="$index==0" ng-click="freelance.addFreelance()" ng-disabled="professional.data.freelance=='false'">
                    </div>                          
                </div>
                </div>

            </div>


            <div class="form-group" ng-controller="NoPsychoWorkController as noPsycho">

                <label class="col-xs-2 control-label">Actividades de trabajo no relacionadas con la psicología</label>

                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" ng-model="professional.data.noPsychoWork" name="optionsTrabajoNoPsicologia" value="true">
                        Sí
                      </label>
                    </div>
                </div>
                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" ng-model="professional.data.noPsychoWork" name="optionsTrabajoNoPsicologia" value="false" ng-change="noPsycho.notNoPsychoWorks()">
                        No
                      </label>
                    </div>
                </div>  

                <div ng-repeat="n in noPsycho.noPsychoWorks track by $index">
                <div class="padding-between-lines">
                    <label class="col-xs-4" ng-hide="$index==0"></label>
                    <div class="col-xs-7">
                            <input type="text" class="form-control" placeholder="Actividad" ng-model="noPsycho.noPsychoWorks[$index]" ng-disabled="professional.data.noPsychoWork=='false'">
                    </div>

                    <div class="col-xs-1">
                        <input type="button" class="añadirTrabajoNoPsicologia form-control" value="Añadir" ng-show="$index==0" ng-click="noPsycho.addNoPsychoWork()" ng-disabled="professional.data.noPsychoWork=='false'">
                    </div>
                </div>
                </div>

            </div>

            <div class="col-xs-offset-2 col-xs-10" ng-controller="PsicologoController as psi">
                <input type="button" class="btn btn-primary btnSeccion" id="btnSeccion2" value="Continuar" ng-click="psi.print()"/>
            </div>

        </form>
    </div>

    <div class="container" id="seccionRegistro3" ng-controller="ProfessionalInterestsController as interests">
        <form class="form-horizontal" role="form">

            <div class="form-group">

                <label for="actividadesInteres" class="col-xs-2 control-label">Actvidades profesionales en las que le gustaría participar</label>

                <div class="col-xs-10" >
                    <label class="checkbox-inline" ng-repeat="area in ['Conferencias y encuentros', 'Cursos', 'Talleres', 'Diplomados', 'Maestría', 'Doctorado']">
                    <input type="checkbox" class="areaTrabajo" checklist-model="interests.data.activities" checklist-value="area"> {{area}}
                    </label>          
                </div>
            </div>

            <div class="form-group">
                <label for="capacitacionInteres" class="col-xs-2 control-label">Areas de la psicología en las que le gustaría capacitarse</label>


                <div class="col-xs-10">
                    <label class="checkbox-inline" ng-repeat="area in ['Clínica', 'Social', 'Laboral', 'Educativa']">
                    <input type="checkbox" class="areaTrabajo" checklist-model="interests.data.trainingAreas" checklist-value="area"> {{area}}
                    </label>
                </div>
            </div>

            <div class="form-group" ng-controller="TrainingTopicsController as trainingTopic">
                <label for="inputNombre" class="col-xs-2 control-label">¿Alguna temática en particular que le gustaría conocer o capacitarse?</label>

                <div ng-repeat="tp in trainingTopic.trainingTopics track by $index">
                    <div class="padding-between-lines">
                        <label class="col-xs-2 control-label" ng-hide="$index==0"></label>
                        <div class="col-xs-9">
                          <input type="text" class="form-control" placeholder="Temática de interés" ng-model="trainingTopic.trainingTopics[$index]">
                        </div>
                        <div class="col-xs-1">
                            <input type="button" class="añadirTemaInteres form-control" value="Añadir" ng-show="$index==0" ng-click="trainingTopic.add()">
                        </div>                                      
                    </div>
                </div>
            </div>

            <div class="form-group" ng-controller="GroupsController as group">

                <label for="checkPosgrado" class="col-xs-2 control-label">¿Pertenece a alguna agrupación relacionada con el campo de la psicología?</label>

                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" name="optionsPertenenciaAgrupacion" value="true" ng-model="interests.data.belongsToSomewhere">
                        Sí
                      </label>
                    </div>
                </div>
                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" name="optionsPertenenciaAgrupacion" value="false" ng-model="interests.data.belongsToSomewhere" ng-change="group.doesntBelongToAnywhere()">
                        No
                      </label>
                    </div>
                </div>  

                <div ng-repeat="g in group.groups track by $index">
                    <div class="padding-between-lines">
                        <label class="col-xs-2 control-label" ng-hide="$index==0"></label>
                        <div class="col-xs-7">
                        <input type="text" class="inputAgrupacion form-control" placeholder="Agrupación" ng-model="group.groups[$index]" ng-disabled="interests.data.belongsToSomewhere=='false'">
                        </div>
                        <div class="col-xs-1">
                        <input type="button" class="form-control" value="Añadir" ng-show="$index==0" ng-click="group.add()" ng-disabled="interests.data.belongsToSomewhere=='false'">
                        </div>                                  
                    </div>
                </div>

            </div>

            <div class="form-group">

                <label for="participacionEventos" class="col-xs-2 control-label">¿Ha participado con anterioridad en algún evento de la Asociación de Psicólogos de Tuxtepec?</label>

                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" name="optionsParticipacionEventos" value="true" ng-model="interests.data.hasParticipated">
                        Sí
                      </label>
                    </div>
                </div>
                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" name="optionsParticipacionEventos" value="false" ng-model="interests.data.hasParticipated">
                        No
                      </label>
                    </div>
                </div>                      

                <div class="col-xs-8">
                    <select multiple class="form-control">
                      <option value="abrazoterapia">Abrazoterapia</option>
                      <option value="tallerMujeres">Taller autoestima mujeres</option>
                    </select>
                </div>
            </div>

            <div class="row">

                <div class="col-xs-6">
                    <h4>Le gustaría participar como miembro activo de la Asociación de Psicólogos de Tuxtepec A.C</h4>
                </div>

                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" name="optionsMiembro" value="true" ng-model="interests.data.wantsToBelong">
                        Sí
                      </label>
                    </div>
                </div>
                <div class="col-xs-1">
                    <div class="radio">
                      <label>
                        <input type="radio" name="optionsMiembro" value="false" ng-model="interests.data.wantsToBelong">
                        No
                      </label>
                    </div>
                </div>  

                <div class="col-xs-4">
                    <textarea class="form-control" rows="3" placeholder="¿Por qué?" ng-model="interests.data.whyToBelong"></textarea>
                </div>



            </div>

            <div class="col-xs-offset-2 col-xs-10" ng-controller="PsicologoController as psi">
                <input type="button" class="btn btn-primary btnSeccion" id="btnSeccion3" value="Finalizar" ng-click="psi.toMongo()"/>
            </div>

            </form>
        </div>
</div>
diegoaguilar
  • 7,496
  • 12
  • 62
  • 120
  • 1
    I assume `professionalData.courses` is actually an array? The problem is twofold: Detect whether an object or array is "empty", and remove that value/property. For the former see [Is object empty?](http://stackoverflow.com/q/4994201/218196)For the later, see [How to remove a property from a JavaScript object](http://stackoverflow.com/q/208105/218196) and [Remove specific element from an array?](http://stackoverflow.com/q/5767325/218196). Also related: []() – Felix Kling May 24 '14 at 07:19
  • 2
    Objects can have key-value pairs. But `courses` is not a valid JS object – thefourtheye May 24 '14 at 07:19
  • This is not JSON, it will throw Syntax error. – dfsq May 24 '14 at 07:20
  • 1
    @dfsq Where did you see JSON mentioned ? – Denys Séguret May 24 '14 at 07:20
  • You are right, I meant this is not valid object syntax. – dfsq May 24 '14 at 07:21
  • 1
    @diegoaguilar What kind of answer are you expecting. Why don't you make a recursive function removing what you don't want to keep ? The problem with this question is that it looks like just some work, not like a technical problem. – Denys Séguret May 24 '14 at 07:22
  • Missed my editing window. I meant to add: [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/q/11922383/218196) – Felix Kling May 24 '14 at 07:24
  • I just went to SublimeText and tried to type in the example. Got confused writing a non value object. I just edited – diegoaguilar May 24 '14 at 07:27

1 Answers1

1

Why not just keep it simple and create a solution that works for the given object. You can always refactor it and then come up with a more elegant solution after that. But you'll need to establish a working point just to get you started. I'd also suggestion caution to creating a complex solution too - because after all, schemas can change ( no matter how many times you may be told they won't ).

I'd start out by just creating separate methods to evaluate each piece individually. For instance, create a solution to work with each of your parent keys ( datosPersonales, datosProfesionales, interesesProfesionales ) that will just determine if they are empty first.

Next, create a solution to work with each sibling of those parents ( postgraduates would have its own routine to check for empty values, works would have its own, etc. ).

Follow this for each branch in the object.

Once you get something that can evaluate each one of them, you'll then be able to start refactoring by working your way up from the bottom-most level ( for instance, tags would be the bottom most level in your first object example ).

Start combining like methods that seem to do the same job and create a universal method that works for each like structure.

And so on..

Once you get a solution close to what you want, I think that's when you'll either be ready to say "hey, can someone help me refactor this even more?".

A good utility kit to help you on your way is underscore: http://underscorejs.org/#map

hope that helps.

Jonathon Hibbard
  • 1,321
  • 12
  • 18
  • Great answer and advise, I'll try it out. Thanks :) – diegoaguilar May 24 '14 at 08:11
  • 1
    no problemo! Took me years to figure out that simple solutions are easy to refactor into a final solution. its when we try to write a do-it-all-at-once solution out of the gate that our forhead gets bloody from smacking it on the keyboard =P haha. anyways, good luck! seems like a fun puzzle – Jonathon Hibbard May 24 '14 at 08:22
  • The prob is actually at my Angular Code, all those attributes with empty values are there because my bad Controllers :/ – diegoaguilar May 24 '14 at 08:24
  • hmm, i'd try creating a data source object then that just handles the payload coming back - hand off the responsibilities to them and let the controller handle using it ( instead of manipulating ). Controller -> Data Model ( Req Payload, Evaluate, return Obj ). Splitting up the responsibilities can help a lot there. Much easier to work with a 40 line file than a 200 line beast =P – Jonathon Hibbard May 24 '14 at 08:29
  • Go ahead and edit the question - you'll get more people looking at it that way anyways. – Jonathon Hibbard May 24 '14 at 08:32
  • Final thing to point out what i mean here - then i gotta get some sleep heh. I'd take this out side of Angular for now - Just work on it like you would if you were not in angular. Create a JS file to just parse that data object. then, add some logic in to make the request to retrieve it and parse it when it comes back (using what you used previously ). Once you get that working - i'd say you'll be ready to work on the controllers. that's all i meant – Jonathon Hibbard May 24 '14 at 08:41