The problem with waiting until "on-the-job" to teach practical stuff is that it leads to people like we (actually, the company - we strongly recommended NOT hiring contract labor for the job) got to handle some software development on a time-critical project a few years ago.
They had all apparently graduated with "software engineering" degrees, which meant they understood programming paradigms, could write long screeds in Java, and tell their favorite IDE to build an object file. What they did not know was how to deal with a design which wasn't in their received wisdom book of tricks, how to invoke custom scripts in a different language, or how to debug something which wouldn't run on the IDE. They also didn't know how to pass what they learned on to their successors when the 18-month contract ran out, so if one of us got transferred to a different project in the meanwhile, they were back to square one using our documentation (which they couldn't interpret in the first place). We were forbidden to do any of their work for them, or supervise the handoff to the project - that was done by their local supervisors who knew even less than they did. As we had expected, it was a disaster.
So I support anything in an engineering curriculum which forces the student to adapt their theory to real-world situations as part of the completion of a course. None of us in EE could have built a class project in the first place if we didn't learn how to read a data sheet, compare specs and try out components in a test rig. One of the most important things we learned in school was that the part specs, the requirements and the actual components often occupied three different spaces, and part of the solution involved dealing with apparent contradictions and hopefully finding a conjunction of the sets. If I hadn't already done that as part of my course work, I would not have been welcomed into a R&D environment to build some pretty cool hardware - the project managers didn't have time to run a remedial course for engineers.