Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9054957
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T13:49:20+00:00 2026-06-16T13:49:20+00:00

The situation that I’m trying to resolve is how to map a child array

  • 0

The situation that I’m trying to resolve is how to map a child array of json data to my view model. The business logic is that for a given position, there is a collection of projects, with each project having a collection of experiences. If I use the knockout mapper function, I’m able to loop through and populate my experience collection, but my viewModel has computed functions, subscribed events, etc and I’m not sure how to wire up my incoming inner array to that viewModel.

The models (in an abbreviated format)

// for creating project objects
my.Project = function (selectedProject) {
    var self = this;
    self.project = ko.observable();
    self.company = ko.observable();
    self.experiences = ko.observableArray([]);
    self.hourlyRate = ko.observable();
    self.hours = ko.observable();
    self.hoursPerWeek = ko.observable();
    self.hoursTypeId = ko.observable();
    self.id = ko.observable();
    self.maxDate = ko.observable();
    self.minDate = ko.observable();
    self.minDescriptionLength = ko.observable();
    self.memberId = ko.observable();
    self.name = ko.observable(); 
    self.startDate = ko.observable();
    // non-persistable properties
    self.chartVals = ko.observableArray([]);
    self.isSelected = ko.computed(function () {
        if (typeof selectedProject === 'undefined') {
            return false;
        } else {
            return selectedProject === self;
        }
    });
    self.newExperience = ko.observable(new my.Experience());
    self.selectProject = function (p) {
        console.log(p.name());
        $("#selectedProjectName").text(p.name());
    };
    self.enableDetails = function () {
        my.vm.proficencyTip = ko.observable();
        console.log("enableDetails pow");
        return true;
    },
    self.disableDetails = function () {
        console.log('disableDetails mouse-off');
        return false;
    };
    self.isSelectedProficiency = ko.observable(false);
    self.selectedProficiency = function (p) {
        console.log('Proficiency value is ' + p.name);
    };
    self.updateProject = function () {
        my.postProjectData(self);
    };
    self.hoursTypeId.subscribe(function () {
        var endDate = new Date();
        var startDate = new Date();
        if (self.endDate() != "") {
            endDate = $.datepicker.parseDate("mm/dd/yy", self.endDate()); 
        }
        if (self.startDate() != undefined) {
            startDate = $.datepicker.parseDate("mm/dd/yy", self.startDate());
        }
        var days = (endDate - startDate) / 1000 / 60 / 60 / 24;
        var weeks = days / 7;
        if (self.hoursTypeId() == 2) {
            if (self.hoursPerWeek() > 0) {
                self.totalHours((weeks * self.hoursPerWeek()).toFixed(0));
            } else {

            }
        }
        if (self.hoursTypeId() == 1) {
            if (self.totalHours() > 0) {
                self.hoursPerWeek((self.totalHours() / weeks).toFixed(0));
            }
        }
    });
};
// for creating Position Models
my.Experience = function (selectedExperience) {
    var self = this;
    self.id = ko.observable();
    self.projectId = ko.observable();
    self.positionId = ko.observable();
    self.memberId = ko.observable();
    self.frequencyId = ko.observable();
    self.skillName = ko.observable();
    self.skillId = ko.observable();
    self.proficiencyId = ko.observable();
    self.frequencyId = ko.observable();
    self.proficiency = ko.observable();
    self.frequency = ko.observable();
    self.description = ko.observable();
    self.skill = {
        name:ko.observable()
    };
    self.proficiency.subscribe(function () {
        self.proficiencyId = self.proficiency();
        console.log('proficiency subscribed: ' + self.proficiency());
        my.setCounterHint(self.frequency(), self.proficiency(), self.description());

        var tip = "Don't just list those skills your strongest in. It's just as important to add new skills you are aquiring!";
        var result = $.grep(my.ajaxData.member.Proficiencies, function (e) { return e.Id == self.proficiency(); });
        if (result.length == 0) {
            // not found
        } else if (result.length == 1) {
            // access the foo property using result[0].foo
            tip = result[0].Name + ':\nAutonomy: ' + result[0].Autonomy + '\nContext: ' + result[0].nContext + '\nKnowledge: ' + result[0].Knowledge + '\nWorkmanship: ' + result[0].Workmanship;
        } else {
            // multiple items found
        }
        $(".proficiencyTip").attr('title', tip).attr('alt', tip);
        $(".proficiencyQuestionMark").fadeIn('slow');
    });

    self.frequency.subscribe(function () {
        self.frequencyId = self.frequency();
        console.log('frequency subscribed: ' + self.frequency());
        self.frequencyId = self.frequency();
        $("#newExperienceFrequency").val(self.frequencyId);
        my.setCounterHint(self.frequency(), self.proficiency(), self.description());
        var tip;

        $(".frequencyTip").attr('title', tip).attr('alt', tip);
        $(".frequencyQuestionMark").fadeIn('slow');
    });

    self.minDesc = ko.observable(my.getMinDescriptionLen(self.frequency(), self.proficiency()));

    self.mouseoverDescription = function () {
        $(".tip").hide(); 
        $(".descriptionQuestionMark").fadeIn('slow');
    },
    self.mouseoffDescription = function () { 
        $(".descriptionQuestionMark").delay(3000).fadeOut("slow");
    };

    });
};


The function where I'm loading the data.
loadProjectsForPosition = function (position) {
    // if we have no projects, add one 
    if (position.projects.length == 0) {
            position.projects.push(new my.Project()
                        .company(position.company())
                        .companyName(position.companyName())
                        .endDate(position.endDate())
                        .experiences([])
                        .hourlyRate(position.hourlyRate())
                        .hours(position.hours())
                        .maxDate(position.maxDate())
                        .minDate(position.minDate())
                        .memberId(position.memberId())
                        .description("Summarize the project and its objectives here.")
                        .name('New')
                        .positionId(position.positionId())
                        .startDate(position.startDate())
                        .totalHours(position.totalHours())
                );

        $.each(my.ajaxData.member.Projects, function (i, p) { 
            if (p.PositionId == position.id()) {
                position.projects.push(new my.Project(position.projects[0])
                        .chartVals(p.ChartVals)
                        .company(p.Company)
                        .companyName(p.CompanyName)
                        .creditMinutes(p.CreditMinutes)
                        .description(p.Description)
                        .endDate(p.EndDate)
                        **.experiences(p.Experiences)** 
                        .hourlyRate(p.HourlyRate)
                        .hours(p.Hours)
                        .hoursPerWeek(p.HoursPerWeek)
                        .hoursTypeId(p.HoursTypeId)
                        .id(p.Id)
                        .maxDate(p.MaxDate)
                        .minDate(p.MinDate)
                        .minDescriptionLength(p.MinDescriptionLength)
                        .memberId(p.MemberId)
                        .name(p.Name)
                        .positionId(p.PositionId)
                        .startDate(p.StartDate)
                        .totalCompensation(p.TotalCompensation)
                        .totalHours(p.TotalHours)
                        .weightedHours(p.WeightedHours)
                        .isSelectedProficiency(false)
                );
                position.selectedPosition = true;
            }
        });
    };
}

The grandchild has children and grandchildren as well, so as much as I’m searching for an answser to this issue, I’m looking for what the pattern is in knockout mapping for dealing with ‘turtles all the way down’.

As always, thanks for taking a look, sharing your experience and offering your well reasoned opinion.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T13:49:21+00:00Added an answer on June 16, 2026 at 1:49 pm

    If you are going to use the mapping plugin, then you will probably want to look at the mapping options and how to customize how objects are created. The documentation is here: http://knockoutjs.com/documentation/plugins-mapping.html#customizing_object_construction_using_create

    Although, if you already have nice constructor functions for your various objects, then you may not need the mapping plugin at all.

    For example, as you are passing your data through the parent constructor you can do:

    var mappedExperiences = ko.utils.arrayMap(selectedProject.experiences || [], function(item) {
        return new my.Experience(item);
    });
    
    self.experiences(mappedExperiences);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a logic situation that is best described as two Teams trying to
I have a logic situation that is best described as two Teams trying to
I have a situation that I'm trying to make work with an array ,
This is a situation that comes up often: In the View, you have a
I ran into the situation that I need a way to edit the data
I have an interesting situation that has me stumped. It seems that posting appliction/json
I encountered the situation that I needed the model before defining it. In someMethod()
This is a very strange situation that I've come across. Basically, I'm trying to
For every situation that warrants the use of an array ... there is an
I have a situation that has puzzled me for weeks. I am running logic

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.