Hi Tim,
Is there a way that we can install the stable Vapor (eg Vapor 2) and install beta Vapor 3 at the same time and easily do a switch if needed?
Thanks!
Hi Tim,
Is there a way that we can install the stable Vapor (eg Vapor 2) and install beta Vapor 3 at the same time and easily do a switch if needed?
Thanks!
@rubiriffic when you say install Vapor do you mean that framework that powers your application or the toolbox that you run with the vapor
command from the command line?
Iām guessing the framework given there isnāt a beta of the toolbox at the moment and the answer is yes! In a different application. You can have two different applications running two different versions of the framework. To start a Vapor 2 project just run vapor new MyVapor2Project
- just be warned that Vapor 2 is very different to Vapor 3. Hope this helps!
@0xtim is it possible to deploy Vapor 3 apps in production when it is still in beta? Can you include in your lesson, deploy to Digital Ocean too? Thanks.
@rubiriffic yes definitely should be, though there is a nasty compiler bug that is causing issues building in release mode in some circumstances that may cause issues. Unfortunately there wasnāt time to cover deployment in the videos but there are several chapters dedicated to the different options in the book!
@0xtim what if you have two parameters that are dynamic? How do you write it in code?
router.get(String.parameter, ???) { req -> String in
let parameter1 = try req.parameter(String.self)
let parameter2 = try req.parameter(???)
return "\(parameter1) \(parameter2)"
}
req.parameter
will get the next parameter that matches that type. So If you have two strings, you can do:
router.get(String.parameter, String.parameter) { req -> String in
let parameter1 = try req.parameter(String.self)
let parameter2 = try req.parameter(String.self)
return "\(parameter1) \(parameter2)"
}
Note that this could cause routing issues though it you have generic everything and then register a route at /something/else
- you may not get the result you expect
I tried that initially @0xtim but I am not able to pinpoint the strings specifically. Example:
If I decided to use the second parameter only, so I will comment out the first parameter:
router.get(String.parameter, String.parameter) { req -> String in
//let parameter1 = try req.parameter(String.self)
let parameter2 = try req.parameter(String.self)
return "Hello \(parameter2)"
}
Result will be the first parameter instead of the intended second parameter.
Isnāt there a better way to name and access these parameters?
Ah I see. Well I would argue that if you donāt care about the first parameter then it shouldnāt really be dynamic - thatās more of a design issue.
Have a look at the routing docs for Vapor 2 - I believe the :name
format has been carried over to Vapor 3
@0xtim Thanks for this documentation link.
I tried following this: (just changed the drop to router)
router.get(":users", ":id") { request in
guard let username = request.parameters["users"]?.string else {
throw Abort.badRequest
}
guard let userId = request.parameters["id"]?.int else {
throw Abort.badRequest
}
return "You requested User: \(username) #\(userId)"
}
and I received the following errors on the variables username and userId
Cannot call value of non-function type āParameterContainer.Parametersā (aka āArrayā)
So I tried using parameter instead of parameters, just like your initial example, and result is:
Error: Argument passed to call that takes no arguments
I think the only solution is to conform the parameter to Parameterizable first, then set it as a parameter. Is this the best way? Thanks.
Note: Iām just trying to experiment if I can create two dynamic parameters (with same Type) and access the parameter.
Thanks for posting this! I wasnāt looking to use two dynamic parameters but it helped me solve my issues at 7:43 in the video:
get("hello", ":name") {req in
let name = req.parameters["name"]?.string
return "Hello \(name!)!"
}
I was curious about your experiment so I then updated the code to this:
get(":greeting", ":name") {req in
let greeting = req.parameters["greeting"]?.string
let name = req.parameters["name"]?.string
return "\(greeting!) \(name!)!"
}
Which worked for me. Iām not sure if Iām on a different Vapor than you, Iām on 3.1.4
I am getting the following error
Unexpected error: [TCP.TCPError.bind: Address already in use] [/Users/mergner/Desktop/Vapor/HelloVapor/.build/checkouts/sockets.git-972942978533733666/Sources/TCP/Socket/TCPServer.swift:122:33] .
Program ended with exit code: 0
Scanning my machine with a network utility I can see that there is no other usage to port 8080, my /etc/host has an entry for localhost
@0xtim Can you please help with this when you get a chance? Thank you - much appreciated! :]
@ckbrown when you ran vapor new
did you do --branch=beta
? Looks like your on Vapor 2. Note that there is a difference between the Vapor toolbox and the Vapor framework. You can tell the version of the framework by looking at the Package.swift
Let me have an experiment and get back to you
@hjm something will be listening on otherwise add this to you configure.swift and choose a different port number
I am working on the example of this screencast, using Safari 11.0.3, Chrome 64.0.3282.167 , Firefox 58.0.2 as well was Rested 2.7 and Paw 3.1.5 as clients.
When stopping the server with command-. from within Xcode and restarting the server after a small modification then I 'll get this message pretty often. Waiting for some time (finishing CLOSE_WAIT ? ) enables me to start again, so my assumption is that there might be an issue with cleanup of the sockets when stopping the server with command-. from within Xcode.
Using another port is of course a painful workaround as I have a couple of test scripts for PAW and Rested
Others are raising this on Slack - seems like the port isnāt being closed quick enough before the new binary tries to connect. Itās being investigated I imagine, but try stopping before running the app if you see the issue
@ckbrown thanks for trying it out.
Iām on 3.1.4
But iām still having error with your code:
Cannot subscript a value of type āParameterContainer.Parametersā (aka āArrayā) with an index of type āStringā
on both the greeting and name variable.
@rubiriffic what does your Package.swift
say - thatās what points to the version of the framework you are using.
The toolbox is 3.1.4, there is lotās of confusion around this! Iāll try and add a clarification in one of the videos when I re-record them. The snippet that @ckbrown posted looks like Vapor 2